aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ov7670.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ov7670.c')
-rw-r--r--drivers/media/video/ov7670.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 5ed0adc4ca26..03bc369a9e49 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -5,6 +5,8 @@
5 * by Jonathan Corbet with substantial inspiration from Mark 5 * by Jonathan Corbet with substantial inspiration from Mark
6 * McClelland's ovcamchip code. 6 * McClelland's ovcamchip code.
7 * 7 *
8 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
9 *
8 * This file may be distributed under the terms of the GNU General 10 * This file may be distributed under the terms of the GNU General
9 * Public License, version 2. 11 * Public License, version 2.
10 */ 12 */
@@ -15,6 +17,7 @@
15#include <linux/delay.h> 17#include <linux/delay.h>
16#include <linux/videodev.h> 18#include <linux/videodev.h>
17#include <media/v4l2-common.h> 19#include <media/v4l2-common.h>
20#include <media/v4l2-chip-ident.h>
18#include <linux/i2c.h> 21#include <linux/i2c.h>
19 22
20 23
@@ -162,6 +165,10 @@ MODULE_LICENSE("GPL");
162 165
163#define REG_GFIX 0x69 /* Fix gain control */ 166#define REG_GFIX 0x69 /* Fix gain control */
164 167
168#define REG_REG76 0x76 /* OV's name */
169#define R76_BLKPCOR 0x80 /* Black pixel correction enable */
170#define R76_WHTPCOR 0x40 /* White pixel correction enable */
171
165#define REG_RGB444 0x8c /* RGB 444 control */ 172#define REG_RGB444 0x8c /* RGB 444 control */
166#define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */ 173#define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */
167#define R444_RGBX 0x01 /* Empty nibble at end */ 174#define R444_RGBX 0x01 /* Empty nibble at end */
@@ -255,7 +262,7 @@ static struct regval_list ov7670_default_regs[] = {
255 262
256 /* Almost all of these are magic "reserved" values. */ 263 /* Almost all of these are magic "reserved" values. */
257 { REG_COM5, 0x61 }, { REG_COM6, 0x4b }, 264 { REG_COM5, 0x61 }, { REG_COM6, 0x4b },
258 { 0x16, 0x02 }, { REG_MVFP, 0x07|MVFP_MIRROR }, 265 { 0x16, 0x02 }, { REG_MVFP, 0x07 },
259 { 0x21, 0x02 }, { 0x22, 0x91 }, 266 { 0x21, 0x02 }, { 0x22, 0x91 },
260 { 0x29, 0x07 }, { 0x33, 0x0b }, 267 { 0x29, 0x07 }, { 0x33, 0x0b },
261 { 0x35, 0x0b }, { 0x37, 0x1d }, 268 { 0x35, 0x0b }, { 0x37, 0x1d },
@@ -380,6 +387,13 @@ static struct regval_list ov7670_fmt_rgb444[] = {
380 { 0xff, 0xff }, 387 { 0xff, 0xff },
381}; 388};
382 389
390static struct regval_list ov7670_fmt_raw[] = {
391 { REG_COM7, COM7_BAYER },
392 { REG_COM13, 0x08 }, /* No gamma, magic rsvd bit */
393 { REG_COM16, 0x3d }, /* Edge enhancement, denoise */
394 { REG_REG76, 0xe1 }, /* Pix correction, magic rsvd */
395 { 0xff, 0xff },
396};
383 397
384 398
385 399
@@ -483,32 +497,39 @@ static struct ov7670_format_struct {
483 __u32 pixelformat; 497 __u32 pixelformat;
484 struct regval_list *regs; 498 struct regval_list *regs;
485 int cmatrix[CMATRIX_LEN]; 499 int cmatrix[CMATRIX_LEN];
500 int bpp; /* Bytes per pixel */
486} ov7670_formats[] = { 501} ov7670_formats[] = {
487 { 502 {
488 .desc = "YUYV 4:2:2", 503 .desc = "YUYV 4:2:2",
489 .pixelformat = V4L2_PIX_FMT_YUYV, 504 .pixelformat = V4L2_PIX_FMT_YUYV,
490 .regs = ov7670_fmt_yuv422, 505 .regs = ov7670_fmt_yuv422,
491 .cmatrix = { 128, -128, 0, -34, -94, 128 }, 506 .cmatrix = { 128, -128, 0, -34, -94, 128 },
507 .bpp = 2,
492 }, 508 },
493 { 509 {
494 .desc = "RGB 444", 510 .desc = "RGB 444",
495 .pixelformat = V4L2_PIX_FMT_RGB444, 511 .pixelformat = V4L2_PIX_FMT_RGB444,
496 .regs = ov7670_fmt_rgb444, 512 .regs = ov7670_fmt_rgb444,
497 .cmatrix = { 179, -179, 0, -61, -176, 228 }, 513 .cmatrix = { 179, -179, 0, -61, -176, 228 },
514 .bpp = 2,
498 }, 515 },
499 { 516 {
500 .desc = "RGB 565", 517 .desc = "RGB 565",
501 .pixelformat = V4L2_PIX_FMT_RGB565, 518 .pixelformat = V4L2_PIX_FMT_RGB565,
502 .regs = ov7670_fmt_rgb565, 519 .regs = ov7670_fmt_rgb565,
503 .cmatrix = { 179, -179, 0, -61, -176, 228 }, 520 .cmatrix = { 179, -179, 0, -61, -176, 228 },
521 .bpp = 2,
522 },
523 {
524 .desc = "Raw RGB Bayer",
525 .pixelformat = V4L2_PIX_FMT_SBGGR8,
526 .regs = ov7670_fmt_raw,
527 .cmatrix = { 0, 0, 0, 0, 0, 0 },
528 .bpp = 1
504 }, 529 },
505}; 530};
506#define N_OV7670_FMTS (sizeof(ov7670_formats)/sizeof(ov7670_formats[0])) 531#define N_OV7670_FMTS ARRAY_SIZE(ov7670_formats)
507 532
508/*
509 * All formats we support are 2 bytes/pixel.
510 */
511#define BYTES_PER_PIXEL 2
512 533
513/* 534/*
514 * Then there is the issue of window sizes. Try to capture the info here. 535 * Then there is the issue of window sizes. Try to capture the info here.
@@ -685,7 +706,7 @@ static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
685 */ 706 */
686 pix->width = wsize->width; 707 pix->width = wsize->width;
687 pix->height = wsize->height; 708 pix->height = wsize->height;
688 pix->bytesperline = pix->width*BYTES_PER_PIXEL; 709 pix->bytesperline = pix->width*ov7670_formats[index].bpp;
689 pix->sizeimage = pix->height*pix->bytesperline; 710 pix->sizeimage = pix->height*pix->bytesperline;
690 return 0; 711 return 0;
691} 712}
@@ -1270,9 +1291,8 @@ static int ov7670_command(struct i2c_client *client, unsigned int cmd,
1270 void *arg) 1291 void *arg)
1271{ 1292{
1272 switch (cmd) { 1293 switch (cmd) {
1273 case VIDIOC_INT_G_CHIP_IDENT: 1294 case VIDIOC_G_CHIP_IDENT:
1274 * (enum v4l2_chip_ident *) arg = V4L2_IDENT_OV7670; 1295 return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_OV7670, 0);
1275 return 0;
1276 1296
1277 case VIDIOC_INT_RESET: 1297 case VIDIOC_INT_RESET:
1278 ov7670_reset(client); 1298 ov7670_reset(client);