diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-05-22 00:39:00 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-05-22 00:39:00 -0300 |
commit | 126b42f75f3d60cf024d206f8d7fb8680903cf8a (patch) | |
tree | cb5fa82c098dc75d7375490f1fc0535f53dc73c5 | |
parent | 0d37212bd283bdd723e7285a4319e9ead3f7a94d (diff) | |
download | mediapointer-dvb-s2-126b42f75f3d60cf024d206f8d7fb8680903cf8a.tar.gz mediapointer-dvb-s2-126b42f75f3d60cf024d206f8d7fb8680903cf8a.tar.bz2 |
Ov7670: reset clkrc in rgb565 mode
From: Jonathan Corbet <corbet@lwn.net>
A bug in the ov7670 sensor causes it to introduce noise unless the CLKRC
register is rewritten *after* setting the image mode. Naturally,
resetting CLKRC in this way will cause other modes to fail. So
carefully poke the register only when indicated.
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | linux/drivers/media/video/ov7670.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/linux/drivers/media/video/ov7670.c b/linux/drivers/media/video/ov7670.c index 8b2c19df9..dcba098aa 100644 --- a/linux/drivers/media/video/ov7670.c +++ b/linux/drivers/media/video/ov7670.c @@ -742,12 +742,22 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt) struct ov7670_format_struct *ovfmt; struct ov7670_win_size *wsize; struct ov7670_info *info = i2c_get_clientdata(c); - unsigned char com7; + unsigned char com7, clkrc; ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize); if (ret) return ret; /* + * HACK: if we're running rgb565 we need to grab then rewrite + * CLKRC. If we're *not*, however, then rewriting clkrc hoses + * the colors. + */ + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) { + ret = ov7670_read(c, REG_CLKRC, &clkrc); + if (ret) + return ret; + } + /* * COM7 is a pain in the ass, it doesn't like to be read then * quickly written afterward. But we have everything we need * to set it absolutely here, as long as the format-specific @@ -766,7 +776,10 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt) if (wsize->regs) ret = ov7670_write_array(c, wsize->regs); info->fmt = ovfmt; - return 0; + + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0) + ret = ov7670_write(c, REG_CLKRC, clkrc); + return ret; } /* @@ -1311,7 +1324,9 @@ static int ov7670_attach(struct i2c_adapter *adapter) ret = ov7670_detect(client); if (ret) goto out_free_info; - i2c_attach_client(client); + ret = i2c_attach_client(client); + if (ret) + goto out_free_info; return 0; out_free_info: |