Web lists-archives.com

[Spca50x-devs] v4l2 pixart




Attached is a port of the pac207 and a few fixes taken from updated
gspcav1 (support for newer kernels).

Best regards
Alban
diff -uNr gspcav2.orig/gspca_dec.c gspcav2/gspca_dec.c
--- gspcav2.orig/gspca_dec.c	2006-08-13 16:44:59.000000000 +0200
+++ gspcav2/gspca_dec.c	2007-08-02 02:39:30.000000000 +0200
@@ -124,47 +124,227 @@
 
 };
 
+/* Sonix decompressor struct B.S.(2004) */
+struct code_table_t {
+        int is_abs;
+        int len;
+        int val;
+};
+
+
+void pixart_decoder(struct code_table_t *table)
+{
+    int i;
+    int is_abs, val, len;
+    for (i = 0; i < 256; i++) {
+        is_abs = 0;
+        val = 0;
+        len = 0;
+        if ((i & 0xC0) == 0) {
+            /* code 00 */
+            val = 0;
+            len = 2;
+        } else if ((i & 0xC0) == 0x40) {
+            /* code 01 */
+            val = -5;
+            len = 2;
+        } else if ((i & 0xC0) == 0x80) {
+            /* code 10 */
+            val = +5;
+            len = 2;
+        } else if ((i & 0xF0) == 0xC0) {
+            /* code 1100 */
+            val = -10;
+            len = 4;
+        } else if ((i & 0xF0) == 0xD0) {
+            /* code 1101 */
+            val = +10;
+            len = 4;
+        } else if ((i & 0xF8) == 0xE0) {
+            /* code 11100 */
+            val = -15;
+            len = 5;
+        } else if ((i & 0xF8) == 0xE8) {
+            /* code 11101 */
+            val = +15;
+            len = 5;
+        } else if ((i & 0xFC) == 0xF0) {
+            /* code 111100 */
+            val = -20;
+            len = 6;
+        } else if ((i & 0xFC) == 0xF4) {
+            /* code 111101 */
+            val = +20;
+            len = 6;
+        } else if ((i & 0xF8) == 0xF8) {
+            /* code 11111xxxxxx */
+            is_abs = 1;
+            val = 0;
+            len = 5;
+        }
+        table[i].is_abs = is_abs;
+        table[i].val = val;
+        table[i].len = len;
+    }
+}
+
+
+#define CLIP(color) (unsigned char)(((color)>0xFF)?0xff:(((color)<0)?0:(color)))
+
+static inline unsigned char getByte(unsigned char *inp,
+                                    unsigned int bitpos)
+{
+    unsigned char *addr;
+    addr = inp + (bitpos >> 3);
+    return (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
+}
+
+
+static int
+pac_decompress_row(struct code_table_t *table, unsigned char *inp,
+                   unsigned char *outp, int width)
+{
+    int col;
+    int val;
+    int bitpos;
+    unsigned char code;
+
+
+    /* first two pixels are stored as raw 8-bit */
+    *outp++ = inp[2];
+    *outp++ = inp[3];
+    bitpos = 32;
+
+    /* main decoding loop */
+    for (col = 2; col < width; col++) {
+        /* get bitcode */
+
+        code = getByte(inp, bitpos);
+        bitpos += table[code].len;
+
+        /* calculate pixel value */
+        if (table[code].is_abs) {
+            /* absolute value: get 6 more bits */
+            code = getByte(inp, bitpos);
+            bitpos += 6;
+            *outp++ = code & 0xFC;
+        } else {
+            /* relative to left pixel */
+            val = outp[-2] + table[code].val;
+            *outp++ = CLIP(val);
+        }
+    }
+
+    /* return line length, rounded up to next 16-bit word */
+    return 2 * ((bitpos + 15) / 16);
+}
+
+static inline unsigned short getShort(unsigned char *pt)
+{
+    return ((pt[0] << 8) | pt[1]);
+}
+
+
+static int pixart_decompress(struct gspca_rawframe *myframe, int width, int height, unsigned char **outp)
+{
+/* we should received a whole frame with header and EOL marker
+in myframe->data and return a GBRG pattern in frame->tmpbuffer
+remove the header then copy line by line EOL is set with 0x0f 0xf0 marker
+or 0x1e 0xe1 for compressed line*/
+    unsigned char *inp = myframe->data;
+    struct code_table_t table[256];
+    unsigned short word;
+    int row;
+    pixart_decoder(table);
+    /* skip header */
+    inp += 16;
+    /* and ask to go at pixel +1 ?? */
+    (*outp)++;
+
+    /* iterate over all rows */
+    for (row = 0; row < height; row++) {
+        word = getShort(inp);
+        switch (word) {
+        case 0x0FF0:
+            memcpy(*outp, inp + 2, width);
+            inp += (2 + width);
+            break;
+        case 0x1EE1:
+            inp += pac_decompress_row(table, inp, *outp, width);
+            break;
+
+        default:
+            return -1;
+        }
+        *outp += width;
+    }
+    return 0;
+}
+
+
+
+
+
+
+
+
 static int
 gspca_outpicture(struct gspca_rawframe *frame)
 {
-struct gspca_device *gspca_dev = (struct gspca_device *) frame->dev;
-struct gspca_video_queue *queue = &gspca_dev->queue;
-struct gspca_buffer *buf = NULL;
-unsigned char *dataout,*ptout;
-int qindex = gspca_dev->stream_param.qindex*2;
-int height = gspca_dev->stream_param.height;
-int width = gspca_dev->stream_param.width;
-
-if(((frame->data[10] << 8) | frame->data[11] ) != width)
-	return -EIO;
-PDEBUG(3, "get size %d x %d ",width,height);
-
-buf = gspca_queue_next_buffer(queue, buf);
-if ( buf == NULL) {
-	return -ENOBUFS; // 105
-}
-dataout = queue->mem + buf->buf.m.offset;
-ptout = dataout;
-
-memcpy(dataout,JPEGHeader, JPEGHEADER_LENGTH);
- /* setup quantization table */
-    *(dataout + 6) = 0;
-    memcpy(dataout + 7, quant[qindex], 64);
-    *(dataout + 7 + 64) = 1;
-    memcpy(dataout + 8 + 64, quant[qindex+1], 64);
-    *(dataout+141) =height >> 8;
-    *(dataout+142) =height & 0xff;
-    *(dataout+143) =width >> 8 ;
-    *(dataout+144) =width & 0xff;
-    *(dataout+147) = 0x21; // jpgh
-    dataout += JPEGHEADER_LENGTH;
-    memcpy(dataout, frame->data + 16,frame->scanlength-16); 
-    dataout += (frame->scanlength-16);
-    /* in case */
-    *(dataout++) = 0xff;
-    *(dataout++) = 0xd9;
+  struct gspca_device *gspca_dev = (struct gspca_device *) frame->dev;
+  struct gspca_video_queue *queue = &gspca_dev->queue;
+  struct gspca_buffer *buf = NULL;
+  unsigned char *dataout,*ptout;
+  int qindex = gspca_dev->stream_param.qindex*2;
+  int height = gspca_dev->stream_param.height;
+  int width = gspca_dev->stream_param.width;
+
+  buf = gspca_queue_next_buffer(queue, buf);
+  if ( buf == NULL) {
+	  return -ENOBUFS; // 105
+  }
+
+  dataout = queue->mem + buf->buf.m.offset;
+  ptout = dataout;
+
+  switch(gspca_dev->camera.type) {
+  case JPGH:
+    if(((frame->data[10] << 8) | frame->data[11] ) != width)
+	  return -EIO;
+      memcpy(dataout,JPEGHeader, JPEGHEADER_LENGTH);
+      /* setup quantization table */
+      *(dataout + 6) = 0;
+      memcpy(dataout + 7, quant[qindex], 64);
+      *(dataout + 7 + 64) = 1;
+      memcpy(dataout + 8 + 64, quant[qindex+1], 64);
+      *(dataout+141) =height >> 8;
+      *(dataout+142) =height & 0xff;
+      *(dataout+143) =width >> 8 ;
+      *(dataout+144) =width & 0xff;
+      *(dataout+147) = 0x21; // jpgh
+      dataout += JPEGHEADER_LENGTH;
+      memcpy(dataout, frame->data + 16,frame->scanlength-16); 
+      dataout += (frame->scanlength-16);
+      /* in case */
+      *(dataout++) = 0xff;
+      *(dataout++) = 0xd9;
+      buf->buf.bytesused= dataout-ptout;
+      buf->state = GSPCA_BUF_STATE_DONE;
+      wake_up(&buf->wait);
+      break;
+  case PGBRG:
+      pixart_decompress(frame, width, height, &dataout);
+      buf->buf.bytesused= dataout-ptout;
+      buf->state = GSPCA_BUF_STATE_DONE;
+      wake_up(&buf->wait);
+      break;
+  default:
+    printk("camera type %d\n", gspca_dev->camera.type);
     buf->buf.bytesused= dataout-ptout;
-buf->state = GSPCA_BUF_STATE_DONE;
-wake_up(&buf->wait);
-return 0;
+    buf->state = GSPCA_BUF_STATE_DONE;
+    wake_up(&buf->wait);
+  } 
+  PDEBUG(3, "get size %d x %d ",width,height);
+
+  return 0;
 }
diff -uNr gspcav2.orig/gspcaV2.c gspcav2/gspcaV2.c
--- gspcav2.orig/gspcaV2.c	2006-09-30 17:12:16.000000000 +0200
+++ gspcav2/gspcaV2.c	2007-08-02 02:50:22.000000000 +0200
@@ -37,7 +37,10 @@
 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+static const char gspca_version[] = GSPCA_VERSION;
+#ifndef AUTOCONF_INCLUDED
 #include <linux/config.h>
+#endif
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/init.h>
@@ -60,13 +63,13 @@
 /* only on 2.6.x */
 #include <linux/jiffies.h>
 #include <linux/param.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
 #include <linux/moduleparam.h>
-
+#endif
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
 #include <media/v4l2-common.h>
 #endif
 
-static const char version[] = GSPCA_VERSION;
 #include "gspcaV2.h"
 
 #define DRIVER_VERSION_NUMBER	KERNEL_VERSION(1, 0, 0)
@@ -666,8 +669,12 @@
 #include "Sonix/sonix.h" 
 #endif
 
+#ifdef PIXART	
+#include "Pixart/pac207.h" 
+#endif
+
 static void
-gspca_transfert_complete(struct urb *urb, struct pt_regs *regs);
+gspca_transfert_complete(struct urb *urb);
 static int
 gspca_kill_transfert(struct gspca_device *gspca_dev);
 static int
@@ -889,7 +896,7 @@
 
 	if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
 	    v4l2_buf->memory != V4L2_MEMORY_MMAP) {
-	//debug	
+	//debug
 		return -EINVAL;
 	}
 
@@ -1061,8 +1068,9 @@
 		nextbuf = list_entry(queue->irqqueue.next, struct gspca_buffer,
 					queue);
 		list_del(queue->irqqueue.next);
-	} else
+	} else {
 		nextbuf = NULL;
+	}
 	spin_unlock_irqrestore(&queue->irqlock, flags);
 
 	//buf->buf.sequence = queue->sequence++;
@@ -1097,7 +1105,7 @@
 		altsetting = &intf->altsetting[i];
 		for (j = 0; j < altsetting->desc.bNumEndpoints; ++j) {
 			ep = &altsetting->endpoint[j];
-			PDEBUG(0, "test ISO EndPoint  %d",ep->desc.bEndpointAddress);
+			PDEBUG(0, "test ISO EndPoint  %d %d",ep->desc.bEndpointAddress, gspca_dev->camera.epaddr);
 			if ((ep->desc.bEndpointAddress ==
 			     (gspca_dev->camera.epaddr | USB_DIR_IN))
 			    &&
@@ -1163,7 +1171,7 @@
 	struct urb *urb;
 	__u16 psize;
 	int n,fx;
-	int error = 0;
+	int error = -ENOSPC;
 	if (gspca_dev->streaming)
 		return -EBUSY;
 	gspca_dev->curframe = 0;
@@ -1259,11 +1267,11 @@
 		if ((error = usb_submit_urb(gspca_dev->sbuf[n].urb, GFP_KERNEL)) < 0) {
 			err("init isoc: usb_submit_urb(%d) ret %d", n, error);
 			gspca_kill_transfert(gspca_dev);	
-			return error;
+			break;
 		}
 	
 	}
-	return 0;
+	return error;
 }
 static int
 gspca_kill_transfert(struct gspca_device *gspca_dev)
@@ -1300,8 +1308,13 @@
 * Function processes the finish of the USB transfer by calling 
 * function to move data from USB buffer to internal raw buffer
 ***********************************************************************/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
 static void
 gspca_transfert_complete(struct urb *urb, struct pt_regs *regs)
+#else
+static void
+gspca_transfert_complete(struct urb *urb)
+#endif
 {
 	int i;
 	struct gspca_device *gspca_dev = (struct gspca_device *) urb->context;
@@ -1384,7 +1397,7 @@
 	int err;
 	struct gspca_rawframe *taskletframe = (struct gspca_rawframe *) ptr;
 	taskletframe->scanlength = taskletframe->ptdata - taskletframe->data;
-	
+
 	if ((err = gspca_outpicture(taskletframe)) < 0) {
 		PDEBUG(2, "frame decoder failed (%d)", err);
 		taskletframe->grabstate = GSPCA_BUF_STATE_ERROR;
@@ -1894,6 +1907,8 @@
 	h = (int) fmt->fmt.pix.height;
 	size = wxh_to_size(w,h);
 	format = v4l_to_gspca(fmt->fmt.pix.pixelformat);
+	if(size == CUSTOM && (gspca_dev->camera.mode_cam[size].t_palette & format))
+		return 0;
 	/* all are fine format size exist */
 	if((gspca_dev->camera.mode_cam[size].width == w) &&
 		(gspca_dev->camera.mode_cam[size].height == h) &&
@@ -1901,10 +1916,10 @@
 		/*the format and size exist*/
 		return 0;
 	/* is the palette exist ? */
-	if(gspca_dev->camera.mode_cam[size].t_palette & format){
-		if((err = gspca_get_size(gspca_dev,fmt,size,format)) < 0)
+	if((gspca_dev->camera.mode_cam[size].t_palette & format)
+		&& (err = gspca_get_size(gspca_dev,fmt,size,format)) >= 0){ 
 		/*same format nearest size*/
-			return err;
+		return 0;
 	} else {
 	/* not available try others ? */
 	/*a new format for the same size */
@@ -2090,7 +2105,7 @@
 //spca5xx_initDecoder(spca50x);
 	gspca_dev->user++;
 	file->private_data = vdev;
-	      out:
+      out:
 	mutex_unlock(&gspca_dev->dev_lock);
       out2:
 	if (err) {
@@ -2449,8 +2464,13 @@
 		return gspca_attach_vimicro(gspca_dev);
 #endif
 #ifdef SONIX		
-	if(gspca_check_sonix(gspca_dev,vendor,product))
+	if(gspca_check_sonix(gspca_dev,vendor,product)){
 		return gspca_attach_sonix(gspca_dev);
+	  }
+#endif
+#ifdef PIXART
+	if(gspca_check_pixart(gspca_dev,vendor,product))
+		return gspca_attach_pixart(gspca_dev);
 #endif
 #if 0
 	if(gspca_check_sunplus_jpeg(gspca_dev,vendor,product))
@@ -2461,8 +2481,6 @@
 		return gspca_attach_conexant(gspca_dev);
 	if(gspca_check_etoms(gspca_dev,vendor,product))
 		return gspca_atttach_etoms(gspca_dev);
-	if(gspca_check_pixart(gspca_dev,vendor,product))
-		return gspca_attach_pixart(gspca_dev);
 	if(gspca_check_mars_semi(gspca_dev,vendor,product))
 		return gspca_attach_mars(gspca_dev);
 	if(gspca_check_transvision(gspca_dev,vendor,product))
@@ -2475,8 +2493,9 @@
 {
 int err;	
 /* Initialise the camera bridge */
-	if (gspca_dev->funct.configure(gspca_dev) < 0)
+	if (gspca_dev->funct.configure(gspca_dev) < 0){
 		goto error;
+	}
 	if((err = gspca_set_alt0(gspca_dev)) < 0)
 		return err;
 	if (gspca_get_default_mode(gspca_dev) < 0)
@@ -2515,11 +2534,6 @@
 		err(" Devices not found !! ");
 		goto error;
 	}
-	if(!gspca_dev->camera.type){
-	 	err(" Devices as no stream type !! ");
-		goto error;
-	 }
-	PDEBUG(0, "Camera type %s ", Plist[gspca_dev->camera.type].name);
 	if (!gspca_configure(gspca_dev)) {
 		gspca_dev->user = 0;
 		gspca_dev->last_times = 0;
@@ -2533,6 +2547,11 @@
 		err("Failed to configure camera");
 		goto error;
 	}
+	if(!gspca_dev->camera.type){
+	 	err(" Devices as no stream type !! ");
+		goto error;
+	 }
+	PDEBUG(0, "Camera type %s ", Plist[gspca_dev->camera.type].name);
 /* Init video stuff */
 	gspca_dev->vdev = video_device_alloc();
 	if (!gspca_dev->vdev)
@@ -2618,7 +2637,7 @@
 {
 	if (usb_register(&gspca_driver) < 0)
 		return -1;
-	info("gspca driver %s registered", version);
+	info("gspca driver %s registered", gspca_version);
 	return 0;
 }
 static void __exit
diff -uNr gspcav2.orig/gspcaV2.h gspcav2/gspcaV2.h
--- gspcav2.orig/gspcaV2.h	2006-09-30 19:16:47.000000000 +0200
+++ gspcav2/gspcaV2.h	2007-08-02 02:39:30.000000000 +0200
@@ -20,9 +20,9 @@
 /* Maximum number of video buffers. */
 #define GSPCA_MAX_VIDEO_BUFFERS	32
 /* input ISO_RAWBUFFER */
-#define GSPCA_RAWBUFF 2
+#define GSPCA_RAWBUFF 2 
 /* iso buf submit for completion */
-#define GSPCA_NUMSBUF 2
+#define GSPCA_NUMSBUF 4 /* 2 is problematic on some systems */
 #define ISO_FRAMES_PER_DESC  20	/* Default value, should be reasonable */
 #define V4L2_PIX_FMT_RAW     v4l2_fourcc('P','R','A','W') /* Damned no one used raw in v4l2 */
 /* GSPCA Vid */
diff -uNr gspcav2.orig/Makefile gspcav2/Makefile
--- gspcav2.orig/Makefile	2006-09-30 18:47:43.000000000 +0200
+++ gspcav2/Makefile	2007-08-02 02:39:30.000000000 +0200
@@ -23,7 +23,7 @@
 DEFINES  += -DVIMICRO
 DEFINES  += -DSONIX
 #DEFINES  += -DSUNPLUS
-#DEFINES  += -DPIXART
+DEFINES  += -DPIXART
 #DEFINES  += -DETOMS
 ###
 # Rest of Makefile follows here. You probably won't need to touch this.
diff -uNr gspcav2.orig/Pixart/pac207.h gspcav2/Pixart/pac207.h
--- gspcav2.orig/Pixart/pac207.h	1970-01-01 01:00:00.000000000 +0100
+++ gspcav2/Pixart/pac207.h	2007-08-02 02:39:30.000000000 +0200
@@ -0,0 +1,553 @@
+
+#ifndef PAC207USB_H
+#define PAC207USB_H
+/****************************************************************************
+#	 	Pixart PAC207BCA library                                    #
+# 		Copyright (C) 2005 Thomas Kaiser thomas@xxxxxxxxxxxxxxx     #
+#               Copyleft (C) 2005 Michel Xhaard mxhaard@xxxxxxxx            #
+#                                                                           #
+# This program is free software; you can redistribute it and/or modify      #
+# it under the terms of the GNU General Public License as published by      #
+# the Free Software Foundation; either version 2 of the License, or         #
+# (at your option) any later version.                                       #
+#                                                                           #
+# This program is distributed in the hope that it will be useful,           #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of            #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             #
+# GNU General Public License for more details.                              #
+#                                                                           #
+# You should have received a copy of the GNU General Public License         #
+# along with this program; if not, write to the Free Software               #
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA #
+#                                                                           #
+****************************************************************************/
+
+
+static __u8 pac207_sensor_init[][8] = {
+    {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0},	//2 
+  //{0x10, 0x24, 0x06, 0x12, 0x0c, 0x01, 0x29, 0xf0},	//2 increase the times exposure decrease frame rate
+    {0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xF0, 0x30},	//a reg_10 digital gain Red Green Blue Ggain
+    {0x00, 0x00, 0x00, 0x70, 0xA0, 0xF8, 0x00, 0x00},	//12
+    {0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xA2, 0x02},	//40
+    {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xAF, 0x00},	//42 reg_66 rate control
+};
+
+static __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };	//48 reg_72 Rate Control end BalSize_4a =0x36
+
+/*******************     Camera Interface   ***********************/
+static int pac207_init(struct gspca_device *gspca_dev);
+static void pac207_start(struct gspca_device *gspca_dev);
+static void pac207_stopN(struct gspca_device *gspca_dev);
+static void pac207_stop0(struct gspca_device *gspca_dev);
+static int pac207_config(struct gspca_device *gspca_dev);
+static void pac207_shutdown(struct gspca_device *gspca_dev);
+static int pac207_sofdetect(struct gspca_device *gspca_dev,struct gspca_rawframe *frame, unsigned char *cdata,int *iPix, int seqnum, int *datalength);
+static int pac207_set_control(struct gspca_device *gspca_dev,struct v4l2_control *ctrl);
+static int pac207_get_control(struct gspca_device *gspca_dev,struct v4l2_control *ctrl);
+static int pac207_query_control(struct gspca_device *gspca_dev,struct v4l2_queryctrl *q_ctrl);
+static int
+gspca_check_pixart(struct gspca_device *gspca_dev, __u16 vendor, __u16 product);
+static int
+gspca_attach_pixart(struct gspca_device *gspca_dev);
+static int
+pac207_set_light_freq(struct gspca_device *gspca_dev);
+/*******************************************************************/
+static __u16 pac207_getbrightness(struct gspca_device *gspca_dev);
+static __u16 pac207_getcontrast(struct gspca_device *gspca_dev);
+static __u16 pac207_getcolors(struct gspca_device *gspca_dev);
+static void pac207_setbrightness(struct gspca_device *gspca_dev);
+static void pac207_setcontrast(struct gspca_device *gspca_dev);
+static void pac207_setcolors(struct gspca_device *gspca_dev);
+static void pac207_setAutobright(struct gspca_device *gspca_dev);
+static void pac207_setquality(struct gspca_device *gspca_dev);
+/***************************** Implementation ****************************/
+static struct cam_operation fpac207 = {
+ 	.initialize = pac207_init,
+	.configure = pac207_config,
+	.start = pac207_start,
+	.stopN = pac207_stopN,
+	.stop0 = pac207_stop0,
+	.cam_shutdown = pac207_shutdown,
+	.sof_detect = pac207_sofdetect,
+        .set_ctrl = pac207_set_control,
+        .get_ctrl = pac207_get_control,
+        .query_ctrl = pac207_query_control,
+        .set_light_frequency_filter = pac207_set_light_freq,
+};
+static struct v4l2_queryctrl pac207_controls[GSPCATOT_CTRL] = {
+        {
+            .id      = V4L2_CID_BRIGHTNESS,
+            .type    = V4L2_CTRL_TYPE_INTEGER,
+            .name    = "Brightness",
+            .minimum = 0,
+            .maximum = 255,
+            .step    = 1,
+            .default_value = 128,
+        }, 
+        {
+            .id      = V4L2_CID_CONTRAST,
+            .type    = V4L2_CTRL_TYPE_INTEGER,
+            .name    = "Contrast",
+            .minimum = 0,
+            .maximum = 255,
+            .step    = 1,
+            .default_value = 128,
+        }, 
+        {
+            .id      = V4L2_CID_SATURATION,
+            .type    = V4L2_CTRL_TYPE_INTEGER,
+            .name    = "Colors",
+            .minimum = 0,
+            .maximum = 255,
+            .step    = 1,
+            .default_value = 128,
+        },
+        {
+            .id      = V4L2_CID_AUTO_WHITE_BALANCE,
+            .type    = V4L2_CTRL_TYPE_BOOLEAN, 
+            .name    = "Auto White Balance",
+            .minimum = 0,
+            .maximum = 1,
+            .step    = 1,
+            .default_value = 0, 
+        },
+        {
+            .id      = V4L2_CID_AUTOGAIN,
+            .type    = V4L2_CTRL_TYPE_BOOLEAN,
+            .name    = "Auto Gain Enabled",
+            .minimum = 0,
+            .maximum = 1,
+            .step    = 1,
+            .default_value = 1, 
+        },
+        {
+            .id      = GSPCA_V4L2_CID_LIGHTFREQ, 
+            .type    = V4L2_CTRL_TYPE_INTEGER,
+            .name    = "Light frequency filter",
+            .minimum = 0,
+            .maximum = 2,
+            .step    = 1,
+            .default_value = 0,
+        },
+};
+
+/*******************************************************************/
+static __u16 pac207_getcolors(struct gspca_device *gspca_dev){
+	return 0;
+}
+static void pac207_setcolors(struct gspca_device *gspca_dev)
+{
+	gspca_dev->stream_param.colors = 0;
+}
+static void pac207_stop0(struct gspca_device *gspca_dev){}
+static void pac207_setquality(struct gspca_device *gspca_dev){}
+static int
+pac207_set_light_freq(struct gspca_device *gspca_dev)
+{
+        return 0;
+}
+/*******************     Camera Private     ***********************/
+static void pac207_reg_write(struct usb_device *dev, __u16 index,
+			     __u16 value);
+static void pac207_reg_read(struct usb_device *dev, __u16 index,
+			    __u8 * buffer);
+
+static void pac207_reg_read(struct usb_device *dev, __u16 index,
+			    __u8 * buffer)
+{
+    pac207RegRead(dev, 0x00, 0x00, index, buffer, 1);
+    return;
+}
+
+static void pac207_reg_write(struct usb_device *dev, __u16 index,
+			     __u16 value)
+{
+    pac207RegWrite(dev, 0x00, value, index, NULL, 0);
+    return;
+}
+
+static __u16 pac207_initcontrol(struct gspca_device *gspca_dev)
+{
+        gspca_dev->stream_param.colors = pac207_controls[GSPCA_COLOR].default_value;
+        gspca_dev->stream_param.brightness = pac207_controls[GSPCA_BRIGHT].default_value;
+        gspca_dev->stream_param.contrast = pac207_controls[GSPCA_CONTRAST].default_value;
+        gspca_dev->stream_param.autoexpo = pac207_controls[GSPCA_AUTOEXPO].default_value;
+        return 0;
+}
+
+static __u16
+pac207_getbrightness(struct gspca_device *gspca_dev)
+{
+    __u8 brightness = 0;
+    pac207_reg_read(gspca_dev->dev, 0x0008, &brightness);
+    gspca_dev->stream_param.brightness = brightness;
+    return gspca_dev->stream_param.brightness;
+}
+static __u16
+pac207_getcontrast(struct gspca_device *gspca_dev)
+{
+    __u8 contrast = 0;
+    pac207_reg_read(gspca_dev->dev, 0x000e, &contrast);
+    gspca_dev->stream_param.contrast = contrast << 3;
+    return gspca_dev->stream_param.contrast;
+}
+static void pac207_setcontrast(struct gspca_device *gspca_dev)
+{
+    __u8 contrast = gspca_dev->stream_param.contrast;
+    __u8 previous_contrast = pac207_getcontrast(gspca_dev);
+    int step = 0;
+    if ((contrast - previous_contrast) > 0) {
+      if((contrast - previous_contrast) < 8)
+	step = 1;
+    }
+    
+    contrast = (contrast >> 3) + step;
+    pac207_reg_write(gspca_dev->dev, 0x000e, contrast); // contrast : 0 to 32
+    pac207_reg_write(gspca_dev->dev, 0x13, 0x01);	//load registers to sensor (Bit 0, auto clear)
+    pac207_reg_write(gspca_dev->dev, 0x1c, 0x01);	//not documented
+}
+static void pac207_setbrightness(struct gspca_device *gspca_dev)
+{
+
+    __u8 brightness = gspca_dev->stream_param.brightness;
+    pac207_reg_write(gspca_dev->dev, 0x0008, brightness);
+    pac207_reg_write(gspca_dev->dev, 0x13, 0x01);	//load registers to sensor (Bit 0, auto clear)
+    pac207_reg_write(gspca_dev->dev, 0x1c, 0x01);	//not documented
+}
+static int pac207_query_control(struct gspca_device *gspca_dev, struct v4l2_queryctrl *q_ctrl)
+{
+        int i;
+        for (i = 0; i < GSPCATOT_CTRL; i++)
+                if(q_ctrl->id == pac207_controls[i].id){
+                        memcpy(q_ctrl,&pac207_controls[i],sizeof(struct v4l2_queryctrl));
+                        return 0;
+                }
+        return -EINVAL;
+}
+static int pac207_get_control(struct gspca_device *gspca_dev, struct v4l2_control *ctrl)
+{
+        switch(ctrl->id){
+                case V4L2_CID_BRIGHTNESS:
+                        ctrl->value = pac207_getbrightness(gspca_dev);
+                break;
+                case V4L2_CID_CONTRAST:
+                        ctrl->value = pac207_getcontrast(gspca_dev);
+                break;
+                case V4L2_CID_SATURATION:
+                        ctrl->value = pac207_getcolors(gspca_dev);
+                break;
+                case V4L2_CID_AUTO_WHITE_BALANCE:
+                        ctrl->value = gspca_dev->stream_param.autoexpo;
+                break;
+                case V4L2_CID_AUTOGAIN:
+                        ctrl->value = gspca_dev->stream_param.autoexpo;
+                break;
+                default:
+                return -EINVAL;
+        }
+        return 0;
+}
+static int pac207_set_control(struct gspca_device *gspca_dev, struct v4l2_control *ctrl)
+{
+        int i;
+        for (i = 0; i < GSPCATOT_CTRL; i++)
+                if(ctrl->id == pac207_controls[i].id){
+                        if ( ctrl->value >= pac207_controls[i].minimum &&
+                                ctrl->value <= pac207_controls[i].maximum ){
+                                PDEBUG(0, "Control value %d ",ctrl->value);
+                                switch(ctrl->id){
+                                        case V4L2_CID_BRIGHTNESS:
+                                                gspca_dev->stream_param.brightness = ctrl->value;
+                                                pac207_setbrightness(gspca_dev);
+                                        return 0;
+                                        case V4L2_CID_CONTRAST:
+                                                gspca_dev->stream_param.contrast = ctrl->value;
+                                                pac207_setcontrast(gspca_dev);
+                                        return 0;
+                                        case V4L2_CID_SATURATION:
+                                                gspca_dev->stream_param.colors = ctrl->value;
+                                                pac207_setcolors(gspca_dev);
+                                        return 0;
+                                        case V4L2_CID_AUTO_WHITE_BALANCE:
+                                                gspca_dev->stream_param.autoexpo = ctrl->value;
+                                                pac207_setAutobright(gspca_dev);
+                                        return 0;
+                                        case V4L2_CID_AUTOGAIN:
+                                                gspca_dev->stream_param.autoexpo = ctrl->value;
+                                                pac207_setAutobright(gspca_dev);
+                                        return 0;
+                                        default:
+                                                return -EINVAL;
+                                }
+                        } else
+                                return -ERANGE;
+                }
+
+        return -EINVAL;
+}
+
+
+static int
+pac207_init(struct gspca_device *gspca_dev)
+{
+    __u8 id[] = { 0, 0 };
+    pac207_reg_write(gspca_dev->dev, 0x41, 0x00);	//Turn of LED
+    pac207_reg_read(gspca_dev->dev, 0x0000, &id[0]);
+    pac207_reg_read(gspca_dev->dev, 0x0001, &id[1]);
+    id[0] = ((id[0] & 0x0F) << 4) | ((id[1] & 0xf0) >> 4);
+    id[1] = id[1] & 0x0f;
+    PDEBUG(2, " Pixart Sensor ID 0x%02X Chips ID 0x%02X !!\n", id[0],
+	   id[1]);
+    if (id[0] != 0x27 || id[1] != 0x00)
+	return -ENODEV;
+
+    return 0;
+}
+
+static void
+set_pac207SIF(struct gspca_device *gspca_dev)
+{
+    struct stream_camera *camera = &gspca_dev->camera;
+
+    memset(camera->mode_cam, 0x00, TOTMODE * sizeof(struct mwebcam));
+    camera->mode_cam[SIF].width = 352;
+    camera->mode_cam[SIF].height = 288;
+    camera->mode_cam[SIF].t_palette =
+	P_BAYER;
+    camera->mode_cam[SIF].method = 0;
+    camera->mode_cam[SIF].mode = 0;
+    camera->mode_cam[CIF].width = 320;
+    camera->mode_cam[CIF].height = 240;
+    camera->mode_cam[CIF].t_palette =
+	P_BAYER;
+    camera->mode_cam[CIF].method = 1;
+    camera->mode_cam[CIF].mode = 0;
+    camera->mode_cam[QPAL].width = 192;
+    camera->mode_cam[QPAL].height = 144;
+    camera->mode_cam[QPAL].t_palette =
+	P_BAYER;
+    camera->mode_cam[QPAL].method = 1;
+    camera->mode_cam[QPAL].mode = 1;
+    camera->mode_cam[QSIF].width = 176;
+    camera->mode_cam[QSIF].height = 144;
+    camera->mode_cam[QSIF].t_palette =
+	P_BAYER;
+    camera->mode_cam[QSIF].method = 0;
+    camera->mode_cam[QSIF].mode = 1;
+    camera->mode_cam[QCIF].width = 160;
+    camera->mode_cam[QCIF].height = 120;
+    camera->mode_cam[QCIF].t_palette =
+	P_BAYER;
+    camera->mode_cam[QCIF].method = 1;
+    camera->mode_cam[QCIF].mode = 1;
+    /* test : wild guesses */
+    /*
+    camera->mode_cam[CUSTOM].t_palette =
+	P_BAYER;
+    camera->mode_cam[CUSTOM].method = 1;
+    camera->mode_cam[CUSTOM].mode = 1;
+    */
+    return;
+}
+
+static int
+pac207_config(struct gspca_device *gspca_dev)
+{
+    struct stream_camera *camera = &gspca_dev->camera;
+    camera->epaddr = 0x85;
+    camera->transfert = USB_ENDPOINT_XFER_ISOC;
+    camera->type = PGBRG;
+    PDEBUG(2, "Find Sensor PAC207");
+    gspca_dev->sensor = SENSOR_PAC207;
+    set_pac207SIF(gspca_dev);
+    pac207_reg_write(gspca_dev->dev, 0x41, 0x00);	// 00 Bit_0=Image Format, Bit_1=LED, Bit_2=Compression test mode enable
+    pac207_reg_write(gspca_dev->dev, 0x0f, 0x00);	//Power Control
+    pac207_reg_write(gspca_dev->dev, 0x11, 0x30);	//Analog Bias
+
+    return pac207_initcontrol(gspca_dev);
+}
+
+static void
+pac207_start(struct gspca_device *gspca_dev)
+{
+
+    __u8 buffer;
+    __u8 mode;
+
+    pac207_reg_write(gspca_dev->dev, 0x0f, 0x10);	//Power control (Bit 6-0)
+    pac207RegWrite(gspca_dev->dev, 0x01, 0, 0x0002, pac207_sensor_init[0],
+		   8);
+    pac207RegWrite(gspca_dev->dev, 0x01, 0, 0x000a, pac207_sensor_init[1],
+		   8);
+    pac207RegWrite(gspca_dev->dev, 0x01, 0, 0x0012, pac207_sensor_init[2],
+		   8);
+    pac207RegWrite(gspca_dev->dev, 0x01, 0, 0x0040, pac207_sensor_init[3],
+		   8);
+    pac207RegWrite(gspca_dev->dev, 0x01, 0, 0x0042, pac207_sensor_init[4],
+		   8);
+    pac207RegWrite(gspca_dev->dev, 0x01, 0, 0x0048, PacReg72, 4);
+    //if (gspca_dev->compress) {
+//	pac207_reg_write(gspca_dev->dev, 0x4a, 0x88);	//Compression Balance size 0x88
+  //  } else {
+	pac207_reg_write(gspca_dev->dev, 0x4a, 0xff);	//Compression Balance size
+   // }
+    pac207_reg_write(gspca_dev->dev, 0x4b, 0x00);	//Sram test value
+    pac207_reg_write(gspca_dev->dev, 0x13, 0x01);	//load registers to sensor (Bit 0, auto clear)
+    pac207_reg_write(gspca_dev->dev, 0x1c, 0x01);	//not documented
+    pac207_reg_write(gspca_dev->dev, 0x41, 0x02);	//Image Format (Bit 0), LED (Bit 1), Compression test mode enable (Bit 2)
+
+    if (gspca_dev->mode) {
+	/* 176x144 */
+	pac207_reg_read(gspca_dev->dev, 0x41, &buffer);
+	mode = buffer | 0x01;
+	//mode = buffer | 0x00;
+	pac207_reg_write(gspca_dev->dev, 0x41, mode);	//Set mode
+	pac207_reg_write(gspca_dev->dev, 0x02, 0x04);	//PXCK = 12MHz /n
+	pac207_reg_write(gspca_dev->dev, 0x0e, 0x0f);	//PGA global gain (Bit 4-0)
+	pac207_reg_write(gspca_dev->dev, 0x13, 0x01);	//load registers to sensor (Bit 0, auto clear)
+	pac207_reg_write(gspca_dev->dev, 0x1c, 0x01);	//not documented
+	PDEBUG(1, "pac207_start mode 176x144, mode = %x", mode);
+    } else {
+	/* 352x288 */
+	pac207_reg_read(gspca_dev->dev, 0x41, &buffer);
+	mode = buffer & 0xfe;
+	pac207_reg_write(gspca_dev->dev, 0x41, mode);	//Set mode
+//	if (gspca_dev->compress) {
+//	    pac207_reg_write(gspca_dev->dev, 0x02, 0x04);	//PXCK = 12MHz / n 04
+//	} else {
+	    pac207_reg_write(gspca_dev->dev, 0x02, 0x0a);	//PXCK = 12MHz / n
+//	}
+	pac207_reg_write(gspca_dev->dev, 0x0e, 0x04);	//PGA global gain (Bit 4-0)
+	pac207_reg_write(gspca_dev->dev, 0x13, 0x01);	//load registers to sensor (Bit 0, auto clear)
+	pac207_reg_write(gspca_dev->dev, 0x1c, 0x01);	//not documented
+	PDEBUG(1, "pac207_start mode 352x288, mode = %x", mode);
+    }
+    udelay(1000);
+    pac207_reg_write(gspca_dev->dev, 0x40, 0x01);	//Start ISO pipe
+
+    pac207_setcontrast(gspca_dev);
+    pac207_setbrightness(gspca_dev);
+    pac207_setquality(gspca_dev);
+    pac207_setAutobright(gspca_dev);
+
+    return;
+}
+
+static void pac207_stopN(struct gspca_device *gspca_dev)
+{
+    pac207_reg_write(gspca_dev->dev, 0x40, 0x00);	//Stop ISO pipe
+    pac207_reg_write(gspca_dev->dev, 0x41, 0x00);	//Turn of LED
+    pac207_reg_write(gspca_dev->dev, 0x0f, 0x00);	//Power Control
+    return;
+}
+
+static void pac207_shutdown(struct gspca_device *gspca_dev)
+{
+    pac207_reg_write(gspca_dev->dev, 0x41, 0x00);	//Turn of LED
+    pac207_reg_write(gspca_dev->dev, 0x0f, 0x00);	//Power Control
+    return;
+}
+
+
+#define BLIMIT(bright) (__u8)((bright>0x1a)?0x1a:((bright < 4)? 4:bright))
+
+static void pac207_setAutobright(struct gspca_device *gspca_dev)
+{
+    unsigned long flags;
+    __u8 luma = 0;
+    __u8 luma_mean = 128;
+    __u8 luma_delta = 20;
+    __u8 spring = 5;
+    __u8 Pxclk;
+    int Gbright = 0;
+    
+    
+    pac207_reg_read(gspca_dev->dev, 0x02, &Pxclk);
+    Gbright = Pxclk;
+    spin_lock_irqsave(&gspca_dev->avg_colors.v4l_lock, flags);
+    luma = gspca_dev->avg_colors.avg_lum;
+    spin_unlock_irqrestore(&gspca_dev->avg_colors.v4l_lock, flags);
+    
+    PDEBUG(2, "Pac207 lumamean %d", luma);
+    if ((luma < (luma_mean - luma_delta)) ||
+	(luma > (luma_mean + luma_delta))) {
+	Gbright += ((luma_mean - luma) >> spring);
+	Gbright = BLIMIT(Gbright);
+	PDEBUG(2, "Pac207 Gbright %d", Gbright);
+	pac207_reg_write(gspca_dev->dev, 0x02,(__u8) Gbright);
+	pac207_reg_write(gspca_dev->dev, 0x13, 0x01);	//load registers to sensor (Bit 0, auto clear)
+	pac207_reg_write(gspca_dev->dev, 0x1c, 0x01);	//not documented
+    }
+}
+#undef BLIMIT
+static int pac207_sofdetect(struct gspca_device *gspca_dev,struct gspca_rawframe *frame, unsigned char *cdata,int *iPix, int seqnum, int *datalength)
+{
+		
+		int sof = 0;
+		int p = 0;
+		if (*datalength < 6)
+		    return -1;
+		else {
+		    for (p = 0; p < *datalength - 6; p++) {
+			if ((cdata[0 + p] == 0xFF)
+			    && (cdata[1 + p] == 0xFF)
+			    && (cdata[2 + p] == 0x00)
+			    && (cdata[3 + p] == 0xFF)
+			    && (cdata[4 + p] == 0x96)
+			    ) {
+			    sof = 1;
+			    break;
+			}
+		    }
+
+		    if (sof) {
+#if 1
+		spin_lock(&gspca_dev->avg_colors.v4l_lock);
+		gspca_dev->avg_colors.avg_lum = cdata[p+9] ;
+		spin_unlock(&gspca_dev->avg_colors.v4l_lock);
+		PDEBUG(5, "mean luma %d", gspca_dev->avg_colors.avg_lum);
+#endif
+			// copy the end of data to the current frame
+			memcpy(frame->ptdata, cdata, p);
+			frame->ptdata += p;
+			//totlen += p;
+			*iPix = p;	//copy to the nextframe start at p
+			*datalength -= *iPix;
+			PDEBUG(5,
+			       "Pixartcam header packet found, %d datalength %d !!",
+			       p, *datalength );
+			return 0;
+		    } else {
+		    	*iPix = 0;
+			return (seqnum+1);
+		    }
+
+		}
+}
+
+
+static int
+gspca_attach_pixart(struct gspca_device *gspca_dev)
+{
+        info("USB GSPCA camera found.(PAC207) ");
+        memcpy(&gspca_dev->funct, &fpac207, sizeof (struct cam_operation));
+return 0;
+}
+static int gspca_check_pixart(struct gspca_device *gspca_dev,__u16 vendor,__u16 product)
+{
+        switch(vendor){
+        case VENDOR_PIXART :
+		switch(product){
+		case 0x2460:
+			gspca_dev->desc = PAC207;
+			goto the_end;
+		}
+		break;
+
+	}
+	return 0;
+      the_end:
+	gspca_dev->bridge = BRIDGE_PAC207;
+	return product;
+}
+#endif				// PAC207USB_H
diff -uNr gspcav2.orig/Sonix/sonix.h gspcav2/Sonix/sonix.h
--- gspcav2.orig/Sonix/sonix.h	2006-09-30 17:35:50.000000000 +0200
+++ gspcav2/Sonix/sonix.h	2007-08-02 02:39:30.000000000 +0200
@@ -974,8 +974,12 @@
 			camera->i2c_base = 0x11;
 			break;
 			}
-		break;	
+		break;
+		default:
+		  return 0;
 	}
+
+
 switch (camera->customid){
 	case SN9C105:
 	case SN9C120:
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Spca50x-devs mailing list
Spca50x-devs@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/spca50x-devs