Here's the latest version of the camera driver. It has a few bug fixes;

Jonathan Corbet corbet at lwn.unroutablenet
Thu Nov 9 16:21:21 EST 2006


Commit:     ef9a0d7f893b7a2a281f82a3d2299ec67ac73ccc
Parent:     7c2466af86620cfbf3cb374d52a55f1d9bee8686
commit ef9a0d7f893b7a2a281f82a3d2299ec67ac73ccc
Author:     Jonathan Corbet <corbet at lwn.net>
AuthorDate: Thu Nov 9 16:19:27 2006 -0500
Commit:     Andres Salomon <dilinger at debian.org>
CommitDate: Thu Nov 9 16:19:27 2006 -0500

    Here's the latest version of the camera driver.  It has a few bug fixes;
    I also, through great pain, figured out how to get the sensor to do QCIF
    mode.
    
    There's also a bunch of whitespace fixes
    
    Signed-off-by: Andres Salomon <dilinger at debian.org>
---
 drivers/media/video/cafe_ccic.c |  101 +++++++++++++++++++++------------------
 drivers/media/video/ov7670.c    |   78 +++++++++++++++++++++---------
 2 files changed, 108 insertions(+), 71 deletions(-)

diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index d5cc93c..d68c9f8 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -69,7 +69,7 @@ MODULE_PARM_DESC(alloc_bufs_at_load,
 		"those buffers, but at the cost of nailing down the memory from "
 		"the outset.");
 
-static int n_dma_bufs = 3; 
+static int n_dma_bufs = 3;
 module_param(n_dma_bufs, uint, 0644);
 MODULE_PARM_DESC(n_dma_bufs,
 		"The number of DMA buffers to allocate.  Can be either two "
@@ -81,7 +81,7 @@ MODULE_PARM_DESC(dma_buf_size,
 		"The size of the allocated DMA buffers.  If actual operating "
 		"parameters require larger buffers, an attempt to reallocate "
 		"will be made.");
-		
+
 static int min_buffers = 1;
 module_param(min_buffers, uint, 0644);
 MODULE_PARM_DESC(min_buffers,
@@ -130,10 +130,10 @@ struct cafe_sio_buffer {
  */
 struct cafe_camera
 {
-	enum cafe_state state;  
+	enum cafe_state state;
 	unsigned long flags;   		/* Buffer status, mainly (dev_lock) */
 	int users;			/* How many open FDs */
-	struct file *owner;	 	/* Who has data access (v4l2) */
+	struct file *owner;		/* Who has data access (v4l2) */
 
 	/*
 	 * Subsystem structures.
@@ -161,12 +161,12 @@ struct cafe_camera
 	struct cafe_sio_buffer *sb_bufs; /* The array of housekeeping structs */
 	struct list_head sb_avail;	/* Available for data (we own) (dev_lock) */
 	struct list_head sb_full;	/* With data (user space owns) (dev_lock) */
-	struct tasklet_struct s_tasklet; 
+	struct tasklet_struct s_tasklet;
 
 	/* Current operating parameters */
 	enum v4l2_chip_ident sensor_type;		/* Currently ov7670 only */
 	struct v4l2_pix_format pix_format;
-	
+
 	/* Locks */
 	struct mutex s_mutex; /* Access to this structure */
 	spinlock_t dev_lock;  /* Access to device */
@@ -197,9 +197,9 @@ #define CF_CONFIG_NEEDED 4	/* Must confi
 static void cafe_reset_buffers(struct cafe_camera *cam)
 {
 	int i;
-	
+
 	cam->next_buf = -1;
-	for (i = 0; i < cam->nbufs; i++) 
+	for (i = 0; i < cam->nbufs; i++)
 		clear_bit(i, &cam->flags);
 	cam->specframes = 0;
 }
@@ -255,7 +255,7 @@ static void cafe_remove_dev(struct cafe_
 static struct cafe_camera *cafe_find_dev(int minor)
 {
 	struct cafe_camera *cam;
-	
+
 	mutex_lock(&cafe_dev_list_lock);
 	list_for_each_entry(cam, &cafe_dev_list, dev_list) {
 		if (cam->v4ldev.minor == minor)
@@ -266,12 +266,12 @@ static struct cafe_camera *cafe_find_dev
 	mutex_unlock(&cafe_dev_list_lock);
 	return cam;
 }
-	
+
 
 static struct cafe_camera *cafe_find_by_pdev(struct pci_dev *pdev)
 {
 	struct cafe_camera *cam;
-	
+
 	mutex_lock(&cafe_dev_list_lock);
 	list_for_each_entry(cam, &cafe_dev_list, dev_list) {
 		if (cam->pdev == pdev)
@@ -282,7 +282,7 @@ static struct cafe_camera *cafe_find_by_
 	mutex_unlock(&cafe_dev_list_lock);
 	return cam;
 }
-	
+
 
 /* ------------------------------------------------------------------------ */
 /*
@@ -374,7 +374,7 @@ static int cafe_smbus_write_data(struct 
 	spin_lock_irqsave(&cam->dev_lock, flags);
 	rval = cafe_reg_read(cam, REG_TWSIC1);
 	spin_unlock_irqrestore(&cam->dev_lock, flags);
-	
+
 	if (rval & TWSIC1_WSTAT) {
 		cam_err(cam, "SMBUS write (%02x/%02x/%02x) timed out\n", addr,
 				command, value);
@@ -433,7 +433,7 @@ static int cafe_smbus_read_data(struct c
 	spin_lock_irqsave(&cam->dev_lock, flags);
 	rval = cafe_reg_read(cam, REG_TWSIC1);
 	spin_unlock_irqrestore(&cam->dev_lock, flags);
-	
+
 	if (rval & TWSIC1_ERROR) {
 		cam_err(cam, "SMBUS read (%02x/%02x) error\n", addr, command);
 		return -EIO;
@@ -457,7 +457,7 @@ static int cafe_smbus_xfer(struct i2c_ad
 {
 	struct cafe_camera *cam = i2c_get_adapdata(adapter);
 	int ret = -EINVAL;
-	
+
 	/*
 	 * Refuse to talk to anything but OV cam chips.  We should
 	 * never even see an attempt to do so, but one never knows.
@@ -492,7 +492,7 @@ #endif
 static void cafe_smbus_enable_irq(struct cafe_camera *cam)
 {
 	unsigned long flags;
-	
+
 	spin_lock_irqsave(&cam->dev_lock, flags);
 	cafe_reg_set_bit(cam, REG_IRQMASK, TWSIIRQS);
 	spin_unlock_irqrestore(&cam->dev_lock, flags);
@@ -511,6 +511,8 @@ static struct i2c_algorithm cafe_smbus_a
 
 /* Somebody is on the bus */
 static int cafe_cam_init(struct cafe_camera *cam);
+static void cafe_ctlr_stop_dma(struct cafe_camera *cam);
+static void cafe_ctlr_power_down(struct cafe_camera *cam);
 
 static int cafe_smbus_attach(struct i2c_client *client)
 {
@@ -531,8 +533,13 @@ static int cafe_smbus_detach(struct i2c_
 {
 	struct cafe_camera *cam = i2c_get_adapdata(client->adapter);
 
-	if (cam->sensor == client)
+	if (cam->sensor == client) {
+		cafe_ctlr_stop_dma(cam);
+		cafe_ctlr_power_down(cam);
+		cam_err(cam, "lost the sensor!\n");
 		cam->sensor = NULL;  /* Bummer, no camera */
+		cam->state = S_NOTREADY;
+	}
 	return 0;
 }
 
@@ -589,7 +596,7 @@ static void cafe_ctlr_dma(struct cafe_ca
 		cafe_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS);
 	cafe_reg_write(cam, REG_UBAR, 0); /* 32 bits only for now */
 }
-			
+
 static void cafe_ctlr_image(struct cafe_camera *cam)
 {
 	int imgsz;
@@ -606,13 +613,13 @@ static void cafe_ctlr_image(struct cafe_
 	 * Tell the controller about the image format we are using.
 	 */
 	switch (cam->pix_format.pixelformat) {
-    	case V4L2_PIX_FMT_YUYV:
+	case V4L2_PIX_FMT_YUYV:
 	    cafe_reg_write_mask(cam, REG_CTRL0,
 			    C0_DF_YUV|C0_YUV_PACKED|C0_YUVE_YUYV,
 			    C0_DF_MASK);
 	    break;
 
-    	/*
+	/*
 	 * For "fake rgb32" get the image pitch right.
 	 */
 	case V4L2_PIX_FMT_RGB32:
@@ -621,12 +628,12 @@ static void cafe_ctlr_image(struct cafe_
 	    imgsz = ((fmt->height << IMGSZ_V_SHIFT) & IMGSZ_V_MASK) |
 		    ((fmt->bytesperline/2) & IMGSZ_H_MASK);
 	    cafe_reg_write(cam, REG_IMGSIZE, imgsz);
-    	    /* fall into ... */
+	    /* fall into ... */
 	case V4L2_PIX_FMT_RGB444:
 	    cafe_reg_write_mask(cam, REG_CTRL0,
 			    C0_DF_RGB|C0_RGBF_444|C0_RGB4_XRGB,
 			    C0_DF_MASK);
-    		/* Alpha value? */
+		/* Alpha value? */
 	    break;
 
 	case V4L2_PIX_FMT_RGB565:
@@ -717,7 +724,7 @@ static void cafe_ctlr_init(struct cafe_c
 	cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC);
 	cafe_reg_set_bit(cam, REG_GL_IMASK, GIMSK_CCIC_EN);
 	/*
-	 * Make sure it's not powered down. 
+	 * Make sure it's not powered down.
 	 */
 	cafe_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN);
 	/*
@@ -757,7 +764,7 @@ static void cafe_ctlr_stop_dma(struct ca
 	mdelay(1);
 	wait_event_timeout(cam->iowait,
 			!test_bit(CF_DMA_ACTIVE, &cam->flags), HZ);
-	if (test_bit(CF_DMA_ACTIVE, &cam->flags)) 
+	if (test_bit(CF_DMA_ACTIVE, &cam->flags))
 		cam_err(cam, "Timeout waiting for DMA to end\n");
 		/* This would be bad news - what now? */
 	spin_lock_irqsave(&cam->dev_lock, flags);
@@ -780,7 +787,7 @@ static void cafe_ctlr_power_up(struct ca
 	 * wiring).  Control 0 is reset - set to 1 to operate.
 	 * Control 1 is power down, set to 0 to operate.
 	 */
-	cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1);
+	cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */
 	mdelay(1); /* Marvell says 1ms will do it */
 	cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
 	mdelay(1); /* Enough? */
@@ -795,7 +802,7 @@ static void cafe_ctlr_power_down(struct 
 	cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1);
 	cafe_reg_set_bit(cam, REG_CTRL1, C1_PWRDWN);
 	spin_unlock_irqrestore(&cam->dev_lock, flags);
-}	
+}
 
 /* -------------------------------------------------------------------- */
 /*
@@ -872,12 +879,12 @@ static int cafe_cam_configure(struct caf
 {
 	struct v4l2_format fmt;
 	int ret, zero = 0;
-	
+
 	if (cam->state != S_IDLE)
 		return -EINVAL;
 	fmt.fmt.pix = cam->pix_format;
 	ret = __cafe_cam_cmd(cam, VIDIOC_INT_INIT, &zero);
-	if (ret == 0) 
+	if (ret == 0)
 		ret = __cafe_cam_cmd(cam, VIDIOC_S_FMT, &fmt);
 	/*
 	 * OV7670 does weird things if flip is set *before* format...
@@ -900,7 +907,7 @@ static int cafe_alloc_dma_bufs(struct ca
 	int i;
 
 	cafe_set_config_needed(cam, 1);
-	if (loadtime) 
+	if (loadtime)
 		cam->dma_buf_size = dma_buf_size;
 	else {
 		cam->dma_buf_size = cam->pix_format.sizeimage;
@@ -940,7 +947,7 @@ static int cafe_alloc_dma_bufs(struct ca
 	}
 	return 0;
 }
-		
+
 static void cafe_free_dma_bufs(struct cafe_camera *cam)
 {
 	int i;
@@ -963,7 +970,7 @@ static void cafe_free_dma_bufs(struct ca
  */
 
 /*
- * Read an image from the device. 
+ * Read an image from the device.
  */
 static ssize_t cafe_deliver_buffer(struct cafe_camera *cam,
 		char __user *buffer, size_t len, loff_t *pos)
@@ -988,11 +995,11 @@ static ssize_t cafe_deliver_buffer(struc
 
 	if (len > cam->pix_format.sizeimage)
 		len = cam->pix_format.sizeimage;
-	if (copy_to_user(buffer, cam->dma_bufs[bufno], len)) 
+	if (copy_to_user(buffer, cam->dma_bufs[bufno], len))
 		return -EFAULT;
 	(*pos) += len;
 	return len;
-}	
+}
 
 /*
  * Get everything ready, and start grabbing frames.
@@ -1001,12 +1008,12 @@ static int cafe_read_setup(struct cafe_c
 {
 	int ret;
 	unsigned long flags;
-	
+
 	/*
 	 * Configuration.  If we still don't have DMA buffers,
 	 * make one last, desperate attempt.
 	 */
-	if (cam->nbufs == 0) 
+	if (cam->nbufs == 0)
 		if (cafe_alloc_dma_bufs(cam, 0))
 			return -ENOMEM;
 
@@ -1035,7 +1042,7 @@ static ssize_t cafe_v4l_read(struct file
 {
 	struct cafe_camera *cam = filp->private_data;
 	int ret;
-	
+
 	/*
 	 * Perhaps we're in speculative read mode and already
 	 * have data?
@@ -1155,7 +1162,7 @@ static int cafe_vidioc_streamoff(struct 
 static int cafe_setup_siobuf(struct cafe_camera *cam, int index)
 {
 	struct cafe_sio_buffer *buf = cam->sb_bufs + index;
-	
+
 	INIT_LIST_HEAD(&buf->list);
 	buf->v4lbuf.length = PAGE_ALIGN(cam->pix_format.sizeimage);
 	buf->buffer = vmalloc_user(buf->v4lbuf.length);
@@ -1438,7 +1445,7 @@ static int cafe_v4l_mmap(struct file *fi
 	mutex_unlock(&cam->s_mutex);
 	return ret;
 }
-	
+
 
 
 static int cafe_v4l_open(struct inode *inode, struct file *filp)
@@ -1466,7 +1473,7 @@ static int cafe_v4l_open(struct inode *i
 static int cafe_v4l_release(struct inode *inode, struct file *filp)
 {
 	struct cafe_camera *cam = filp->private_data;
-	
+
 	mutex_lock(&cam->s_mutex);
 	(cam->users)--;
 	if (filp == cam->owner) {
@@ -1500,7 +1507,7 @@ static int cafe_vidioc_queryctrl(struct 
 {
 	struct cafe_camera *cam = filp->private_data;
 	int ret;
-	
+
 	mutex_lock(&cam->s_mutex);
 	ret = __cafe_cam_cmd(cam, VIDIOC_QUERYCTRL, qc);
 	mutex_unlock(&cam->s_mutex);
@@ -1513,7 +1520,7 @@ static int cafe_vidioc_g_ctrl(struct fil
 {
 	struct cafe_camera *cam = filp->private_data;
 	int ret;
-	
+
 	mutex_lock(&cam->s_mutex);
 	ret = __cafe_cam_cmd(cam, VIDIOC_G_CTRL, ctrl);
 	mutex_unlock(&cam->s_mutex);
@@ -1526,7 +1533,7 @@ static int cafe_vidioc_s_ctrl(struct fil
 {
 	struct cafe_camera *cam = filp->private_data;
 	int ret;
-	
+
 	mutex_lock(&cam->s_mutex);
 	ret = __cafe_cam_cmd(cam, VIDIOC_S_CTRL, ctrl);
 	mutex_unlock(&cam->s_mutex);
@@ -1642,7 +1649,7 @@ static int cafe_vidioc_g_fmt_cap(struct 
 		struct v4l2_format *f)
 {
 	struct cafe_camera *cam = priv;
-	
+
 	f->fmt.pix = cam->pix_format;
 	return 0;
 }
@@ -1846,7 +1853,7 @@ static void cafe_frame_complete(struct c
 	 * Basic frame housekeeping.
 	 */
 	if (test_bit(frame, &cam->flags) && printk_ratelimit())
-		cam_err(cam, "Frame overrun on %d, frames lost\n", frame);		
+		cam_err(cam, "Frame overrun on %d, frames lost\n", frame);
 	set_bit(frame, &cam->flags);
 	clear_bit(CF_DMA_ACTIVE, &cam->flags);
 	if (cam->next_buf < 0)
@@ -1862,7 +1869,7 @@ static void cafe_frame_complete(struct c
 		cam->specframes = 0;
 		wake_up(&cam->iowait);
 		break;
-		
+
 	/*
 	 * If we are already doing speculative reads, and nobody is
 	 * reading them, just stop.
@@ -1994,7 +2001,7 @@ static ssize_t cafe_dfs_read_regs(struct
 	return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf,
 			s - cafe_debug_buf);
 }
-		
+
 static struct file_operations cafe_dfs_reg_ops = {
 	.owner = THIS_MODULE,
 	.read = cafe_dfs_read_regs,
@@ -2185,7 +2192,7 @@ static void cafe_shutdown(struct cafe_ca
 	video_unregister_device(&cam->v4ldev);
 	/* kfree(cam); done in v4l_release () */
 }
-		
+
 
 static void cafe_pci_remove(struct pci_dev *pdev)
 {
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index deb6e5a..466d6e9 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -179,7 +179,7 @@ static struct regval_list ov7670_default
  *              2 = 20fps
  *              1 = 30fps
  */
-	{ REG_CLKRC, 0x1 },	/* OV: clock scale (15 fps) */
+	{ REG_CLKRC, 0x1 },	/* OV: clock scale (30 fps) */
 	{ REG_TSLB,  0x04 },	/* OV */
 	{ REG_COM7, 0 },	/* VGA */
 	/*
@@ -195,7 +195,7 @@ static struct regval_list ov7670_default
 	{ 0x70, 0x3a },		{ 0x71, 0x35 },
 	{ 0x72, 0x11 },		{ 0x73, 0xf0 },
 	{ 0xa2, 0x02 },		{ REG_COM10, 0x0 },
-	
+
 	/* Gamma curve values */
 	{ 0x7a, 0x20 },		{ 0x7b, 0x10 },
 	{ 0x7c, 0x1e },		{ 0x7d, 0x35 },
@@ -220,7 +220,7 @@ static struct regval_list ov7670_default
 	{ REG_HAECC5, 0xf0 },	{ REG_HAECC6, 0x90 },
 	{ REG_HAECC7, 0x94 },
 	{ REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC },
-	
+
 	/* Almost all of these are magic "reserved" values.  */
 	{ REG_COM5, 0x61 },	{ REG_COM6, 0x4b },
 	{ 0x16, 0x02 },		{ REG_MVFP, 0x07|MVFP_MIRROR },
@@ -256,7 +256,7 @@ static struct regval_list ov7670_default
 	{ 0x51, 0 },		{ 0x52, 0x22 },
 	{ 0x53, 0x5e },		{ 0x54, 0x80 },
 	{ 0x58, 0x9e },
-	
+
 	{ REG_COM16, COM16_AWBGAIN },	{ REG_EDGE, 0 },
 	{ 0x75, 0x05 },		{ 0x76, 0xe1 },
 	{ 0x4c, 0 },		{ 0x77, 0x01 },
@@ -286,10 +286,6 @@ static struct regval_list ov7670_default
 	{ 0x79, 0x05 },		{ 0xc8, 0x30 },
 	{ 0x79, 0x26 },
 
-	/* Not sure if these should be here */
-	{ 0xf1, 0x10 },		{ 0x0f, 0x1d },
-	{ 0x0f, 0x1f },
-
 	{ 0xff, 0xff },	/* END MARKER */
 };
 
@@ -489,6 +485,7 @@ static struct ov7670_format_struct {
 		.pixelformat	= V4L2_PIX_FMT_RGB565,
 		.regs		= ov7670_fmt_rgb565,
 	},
+#if 0
 	/*
 	 * Pretend we do RGB32.  This is here on the assumption that the
 	 * upper layer will reformat RGB444 appropriately.
@@ -501,6 +498,7 @@ static struct ov7670_format_struct {
 		.pixelformat	= V4L2_PIX_FMT_RGB32,
 		.regs		= ov7670_fmt_rgb444,
 	},
+#endif
 };
 #define N_OV7670_FMTS (sizeof(ov7670_formats)/sizeof(ov7670_formats[0]))
 
@@ -512,6 +510,33 @@ #define BYTES_PER_PIXEL 2
 /*
  * Then there is the issue of window sizes.  Try to capture the info here.
  */
+
+/*
+ * QCIF mode is done (by OV) in a very strange way - it actually looks like
+ * VGA with weird scaling options - they do *not* use the canned QCIF mode
+ * which is allegedly provided by the sensor.  So here's the weird register
+ * settings.
+ */
+static struct regval_list ov7670_qcif_regs[] = {
+	{ REG_COM3, COM3_SCALEEN|COM3_DCWEN },
+	{ REG_COM3, COM3_DCWEN },
+	{ REG_COM14, COM14_DCWEN | 0x01},
+	{ 0x73, 0xf1 },
+	{ 0xa2, 0x52 },
+	{ 0x7b, 0x1c },
+	{ 0x7c, 0x28 },
+	{ 0x7d, 0x3c },
+	{ 0x7f, 0x69 },
+	{ REG_COM9, 0x38 },
+	{ 0xa1, 0x0b },
+	{ 0x74, 0x19 },
+	{ 0x9a, 0x80 },
+	{ 0x43, 0x14 },
+	{ REG_RED, 0x60 },
+	{ REG_COM13, 0xc0 },
+	{ 0xff, 0xff },
+};
+
 static struct ov7670_win_size {
 	int	width;
 	int	height;
@@ -520,6 +545,7 @@ static struct ov7670_win_size {
 	int	hstop;		/* that they do not always make complete */
 	int	vstart;		/* sense to humans, but evidently the sensor */
 	int	vstop;		/* will do the right thing... */
+	struct regval_list *regs; /* Regs to tweak */
 /* h/vref stuff */
 } ov7670_win_sizes[] = {
 	/* VGA */
@@ -531,6 +557,7 @@ static struct ov7670_win_size {
 		.hstop		=  14,		/* Omnivision */
 		.vstart		=  10,
 		.vstop		= 490,
+		.regs 		= NULL,
 	},
 	/* CIF */
 	{
@@ -541,6 +568,7 @@ static struct ov7670_win_size {
 		.hstop		=  90,
 		.vstart		=  14,
 		.vstop		= 494,
+		.regs 		= NULL,
 	},
 	/* QVGA */
 	{
@@ -551,19 +579,19 @@ static struct ov7670_win_size {
 		.hstop		=  20,
 		.vstart		=  14,
 		.vstop		= 494,
+		.regs 		= NULL,
 	},
-#if 0 /* Does not work at all yet */
 	/* QCIF */
 	{
 		.width		= QCIF_WIDTH,
 		.height		= QCIF_HEIGHT,
-		.com7_bit	= COM7_FMT_QCIF,
-		.hstart		= 28,		/* Empirically determined */
+		.com7_bit	= COM7_FMT_VGA, /* see comment above */
+		.hstart		= 456,		/* Empirically determined */
 		.hstop		=  24,
 		.vstart		=  14,
 		.vstop		= 494,
+		.regs 		= ov7670_qcif_regs,
 	},
-#endif
 };
 
 #define N_WIN_SIZES (sizeof(ov7670_win_sizes)/sizeof(ov7670_win_sizes[0]))
@@ -604,7 +632,7 @@ static int ov7670_set_hw(struct i2c_clie
 static int ov7670_enum_fmt(struct i2c_client *c, struct v4l2_fmtdesc *fmt)
 {
 	struct ov7670_format_struct *ofmt;
-	
+
 	if (fmt->index >= N_OV7670_FMTS)
 		return -EINVAL;
 
@@ -643,10 +671,10 @@ static int ov7670_try_fmt(struct i2c_cli
 	 * we support, but not below the smallest.
 	 */
 	for (wsize = ov7670_win_sizes; wsize < ov7670_win_sizes + N_WIN_SIZES;
-	     wsize++) 
+	     wsize++)
 		if (pix->width >= wsize->width && pix->height >= wsize->height)
 			break;
-	if (wsize > ov7670_win_sizes + N_WIN_SIZES)
+	if (wsize >= ov7670_win_sizes + N_WIN_SIZES)
 		wsize--;   /* Take the smallest one */
 	if (ret_wsize != NULL)
 		*ret_wsize = wsize;
@@ -660,7 +688,6 @@ static int ov7670_try_fmt(struct i2c_cli
 		pix->bytesperline *= 2;
 	pix->sizeimage = pix->height*pix->bytesperline;
 	return 0;
-
 }
 
 /*
@@ -691,6 +718,9 @@ static int ov7670_s_fmt(struct i2c_clien
 	ov7670_write_array(c, ovfmt->regs + 1);
 	ov7670_set_hw(c, wsize->hstart, wsize->hstop, wsize->vstart,
 			wsize->vstop);
+	ret = 0;
+	if (wsize->regs)
+		ret = ov7670_write_array(c, wsize->regs);
 	return 0;
 }
 
@@ -722,7 +752,7 @@ static int ov7670_t_brightness(struct i2
 {
 	unsigned char com8;
 	int ret;
-	
+
 	ov7670_read(client, REG_COM8, &com8);
 	com8 &= ~COM8_AEC;
 	ov7670_write(client, REG_COM8, com8);
@@ -846,7 +876,7 @@ static struct ov7670_control {
 			.minimum = 0,
 			.maximum = 1,
 			.step = 1,
-			.default_value = 0, 
+			.default_value = 0,
 		},
 		.tweak = ov7670_t_vflip,
 		.query = ov7670_q_vflip,
@@ -859,7 +889,7 @@ static struct ov7670_control {
 			.minimum = 0,
 			.maximum = 1,
 			.step = 1,
-			.default_value = 0, 
+			.default_value = 0,
 		},
 		.tweak = ov7670_t_hflip,
 		.query = ov7670_q_hflip,
@@ -894,7 +924,7 @@ static int ov7670_g_ctrl(struct i2c_clie
 	struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
 	int ret;
 	unsigned char v;
-	
+
 	if (octrl == NULL)
 		return -EINVAL;
 	ret = octrl->query(client, &v);
@@ -908,7 +938,7 @@ static int ov7670_g_ctrl(struct i2c_clie
 static int ov7670_s_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
 {
 	struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
-	
+
 	if (octrl == NULL)
 		return -EINVAL;
 	return octrl->tweak(client, ctrl->value);
@@ -929,7 +959,7 @@ static int ov7670_attach(struct i2c_adap
 {
 	int ret;
 	struct i2c_client *client;
-	
+
 	printk(KERN_ERR "ov7670 attach, id = %d\n", adapter->id);
 	/*
 	 * For now: only deal with adapters we recognize.
@@ -989,11 +1019,11 @@ static int ov7670_command(struct i2c_cli
 	case VIDIOC_ENUM_FMT:
 		return ov7670_enum_fmt(client, (struct v4l2_fmtdesc *) arg);
 	case VIDIOC_TRY_FMT:
-	    	return ov7670_try_fmt(client, (struct v4l2_format *) arg, NULL, NULL);
+		return ov7670_try_fmt(client, (struct v4l2_format *) arg, NULL, NULL);
 	case VIDIOC_S_FMT:
 		return ov7670_s_fmt(client, (struct v4l2_format *) arg);
 	case VIDIOC_QUERYCTRL:
-	    	return ov7670_queryctrl(client, (struct v4l2_queryctrl *) arg);
+		return ov7670_queryctrl(client, (struct v4l2_queryctrl *) arg);
 	case VIDIOC_S_CTRL:
 		return ov7670_s_ctrl(client, (struct v4l2_control *) arg);
 	case VIDIOC_G_CTRL:


More information about the Commits-kernel mailing list