Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 357521
b: refs/heads/master
c: d058e23
h: refs/heads/master
i:
  357519: c440f7b
v: v3
  • Loading branch information
Javier Martin authored and Mauro Carvalho Chehab committed Feb 8, 2013
1 parent cba90d4 commit 5249b81
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 06eae25f162e2a0d9e60f0ad3ec3d14c738fbe68
refs/heads/master: d058e23704ad7e0b6876a94b0d8428dcef510b49
101 changes: 72 additions & 29 deletions trunk/drivers/media/i2c/ov7670.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,27 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
#define REG_BD60MAX 0xab /* 60hz banding step limit */

enum ov7670_model {
MODEL_OV7670 = 0,
MODEL_OV7675,
};

struct ov7670_win_size {
int width;
int height;
unsigned char com7_bit;
int hstart; /* Start/stop values for the camera. Note */
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 */
};

struct ov7670_devtype {
/* formats supported for each model */
struct ov7670_win_size *win_sizes;
unsigned int n_win_sizes;
};

/*
* Information we maintain about a known sensor.
Expand All @@ -198,6 +219,7 @@ struct ov7670_info {
int clock_speed; /* External clock speed (MHz) */
u8 clkrc; /* Clock divider value */
bool use_smbus; /* Use smbus I/O instead of I2C */
const struct ov7670_devtype *devtype; /* Device specifics */
};

static inline struct ov7670_info *to_state(struct v4l2_subdev *sd)
Expand Down Expand Up @@ -652,65 +674,70 @@ static struct regval_list ov7670_qcif_regs[] = {
{ 0xff, 0xff },
};

static struct ov7670_win_size {
int width;
int height;
unsigned char com7_bit;
int hstart; /* Start/stop values for the camera. Note */
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[] = {
static struct ov7670_win_size ov7670_win_sizes[] = {
/* VGA */
{
.width = VGA_WIDTH,
.height = VGA_HEIGHT,
.com7_bit = COM7_FMT_VGA,
.hstart = 158, /* These values from */
.hstop = 14, /* Omnivision */
.hstart = 158, /* These values from */
.hstop = 14, /* Omnivision */
.vstart = 10,
.vstop = 490,
.regs = NULL,
.regs = NULL,
},
/* CIF */
{
.width = CIF_WIDTH,
.height = CIF_HEIGHT,
.com7_bit = COM7_FMT_CIF,
.hstart = 170, /* Empirically determined */
.hstart = 170, /* Empirically determined */
.hstop = 90,
.vstart = 14,
.vstop = 494,
.regs = NULL,
.regs = NULL,
},
/* QVGA */
{
.width = QVGA_WIDTH,
.height = QVGA_HEIGHT,
.com7_bit = COM7_FMT_QVGA,
.hstart = 168, /* Empirically determined */
.hstart = 168, /* Empirically determined */
.hstop = 24,
.vstart = 12,
.vstop = 492,
.regs = NULL,
.regs = NULL,
},
/* QCIF */
{
.width = QCIF_WIDTH,
.height = QCIF_HEIGHT,
.com7_bit = COM7_FMT_VGA, /* see comment above */
.hstart = 456, /* Empirically determined */
.hstart = 456, /* Empirically determined */
.hstop = 24,
.vstart = 14,
.vstop = 494,
.regs = ov7670_qcif_regs,
},
.regs = ov7670_qcif_regs,
}
};

#define N_WIN_SIZES (ARRAY_SIZE(ov7670_win_sizes))

static struct ov7670_win_size ov7675_win_sizes[] = {
/*
* Currently, only VGA is supported. Theoretically it could be possible
* to support CIF, QVGA and QCIF too. Taking values for ov7670 as a
* base and tweak them empirically could be required.
*/
{
.width = VGA_WIDTH,
.height = VGA_HEIGHT,
.com7_bit = COM7_FMT_VGA,
.hstart = 158, /* These values from */
.hstop = 14, /* Omnivision */
.vstart = 14, /* Empirically determined */
.vstop = 494,
.regs = NULL,
}
};

/*
* Store a set of start/stop values into the camera.
Expand Down Expand Up @@ -761,6 +788,8 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
{
int index;
struct ov7670_win_size *wsize;
struct ov7670_info *info = to_state(sd);
unsigned int n_win_sizes = info->devtype->n_win_sizes;

for (index = 0; index < N_OV7670_FMTS; index++)
if (ov7670_formats[index].mbus_code == fmt->code)
Expand All @@ -780,11 +809,11 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
* Round requested image size down to the nearest
* we support, but not below the smallest.
*/
for (wsize = ov7670_win_sizes; wsize < ov7670_win_sizes + N_WIN_SIZES;
wsize++)
for (wsize = info->devtype->win_sizes;
wsize < info->devtype->win_sizes + n_win_sizes; wsize++)
if (fmt->width >= wsize->width && fmt->height >= wsize->height)
break;
if (wsize >= ov7670_win_sizes + N_WIN_SIZES)
if (wsize >= info->devtype->win_sizes + n_win_sizes)
wsize--; /* Take the smallest one */
if (ret_wsize != NULL)
*ret_wsize = wsize;
Expand Down Expand Up @@ -931,13 +960,14 @@ static int ov7670_enum_framesizes(struct v4l2_subdev *sd,
int i;
int num_valid = -1;
__u32 index = fsize->index;
unsigned int n_win_sizes = info->devtype->n_win_sizes;

/*
* If a minimum width/height was requested, filter out the capture
* windows that fall outside that.
*/
for (i = 0; i < N_WIN_SIZES; i++) {
struct ov7670_win_size *win = &ov7670_win_sizes[index];
for (i = 0; i < n_win_sizes; i++) {
struct ov7670_win_size *win = &info->devtype->win_sizes[index];
if (info->min_width && win->width < info->min_width)
continue;
if (info->min_height && win->height < info->min_height)
Expand Down Expand Up @@ -1510,6 +1540,17 @@ static const struct v4l2_subdev_ops ov7670_ops = {

/* ----------------------------------------------------------------------- */

static const struct ov7670_devtype ov7670_devdata[] = {
[MODEL_OV7670] = {
.win_sizes = ov7670_win_sizes,
.n_win_sizes = ARRAY_SIZE(ov7670_win_sizes),
},
[MODEL_OV7675] = {
.win_sizes = ov7675_win_sizes,
.n_win_sizes = ARRAY_SIZE(ov7675_win_sizes),
},
};

static int ov7670_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
Expand Down Expand Up @@ -1551,6 +1592,7 @@ static int ov7670_probe(struct i2c_client *client,
v4l_info(client, "chip found @ 0x%02x (%s)\n",
client->addr << 1, client->adapter->name);

info->devtype = &ov7670_devdata[id->driver_data];
info->fmt = &ov7670_formats[0];
info->sat = 128; /* Review this */
info->clkrc = info->clock_speed / 30;
Expand All @@ -1568,7 +1610,8 @@ static int ov7670_remove(struct i2c_client *client)
}

static const struct i2c_device_id ov7670_id[] = {
{ "ov7670", 0 },
{ "ov7670", MODEL_OV7670 },
{ "ov7675", MODEL_OV7675 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ov7670_id);
Expand Down

0 comments on commit 5249b81

Please sign in to comment.