Commit 4ead9630 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] ov772x: Compute window size registers at runtime

Instead of hardcoding register arrays, compute the values at runtime.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
[g.liakhovetski@gmx.de: keep (Q)VGA_* macros for now]
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent f223d5b7
...@@ -318,8 +318,15 @@ ...@@ -318,8 +318,15 @@
#define SGLF_ON_OFF 0x02 /* Single frame ON/OFF selection */ #define SGLF_ON_OFF 0x02 /* Single frame ON/OFF selection */
#define SGLF_TRIG 0x01 /* Single frame transfer trigger */ #define SGLF_TRIG 0x01 /* Single frame transfer trigger */
/* HREF */
#define HREF_VSTART_SHIFT 6 /* VSTART LSB */
#define HREF_HSTART_SHIFT 4 /* HSTART 2 LSBs */
#define HREF_VSIZE_SHIFT 2 /* VSIZE LSB */
#define HREF_HSIZE_SHIFT 0 /* HSIZE 2 LSBs */
/* EXHCH */ /* EXHCH */
#define VSIZE_LSB 0x04 /* Vertical data output size LSB */ #define EXHCH_VSIZE_SHIFT 2 /* VOUTSIZE LSB */
#define EXHCH_HSIZE_SHIFT 0 /* HOUTSIZE 2 LSBs */
/* DSP_CTRL1 */ /* DSP_CTRL1 */
#define FIFO_ON 0x80 /* FIFO enable/disable selection */ #define FIFO_ON 0x80 /* FIFO enable/disable selection */
...@@ -345,30 +352,6 @@ ...@@ -345,30 +352,6 @@
#define DSP_OFMT_RAW8 0x02 #define DSP_OFMT_RAW8 0x02
#define DSP_OFMT_RAW10 0x03 #define DSP_OFMT_RAW10 0x03
/* HSTART */
#define HST_VGA 0x23
#define HST_QVGA 0x3F
/* HSIZE */
#define HSZ_VGA 0xA0
#define HSZ_QVGA 0x50
/* VSTART */
#define VST_VGA 0x07
#define VST_QVGA 0x03
/* VSIZE */
#define VSZ_VGA 0xF0
#define VSZ_QVGA 0x78
/* HOUTSIZE */
#define HOSZ_VGA 0xA0
#define HOSZ_QVGA 0x50
/* VOUTSIZE */
#define VOSZ_VGA 0xF0
#define VOSZ_QVGA 0x78
/* DSPAUTO (DSP Auto Function ON/OFF Control) */ /* DSPAUTO (DSP Auto Function ON/OFF Control) */
#define AWB_ACTRL 0x80 /* AWB auto threshold control */ #define AWB_ACTRL 0x80 /* AWB auto threshold control */
#define DENOISE_ACTRL 0x40 /* De-noise auto threshold control */ #define DENOISE_ACTRL 0x40 /* De-noise auto threshold control */
...@@ -377,6 +360,13 @@ ...@@ -377,6 +360,13 @@
#define SCAL0_ACTRL 0x08 /* Auto scaling factor control */ #define SCAL0_ACTRL 0x08 /* Auto scaling factor control */
#define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */ #define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */
#define VGA_WIDTH 640
#define VGA_HEIGHT 480
#define QVGA_WIDTH 320
#define QVGA_HEIGHT 240
#define OV772X_MAX_WIDTH VGA_WIDTH
#define OV772X_MAX_HEIGHT VGA_HEIGHT
/* /*
* ID * ID
*/ */
...@@ -387,10 +377,6 @@ ...@@ -387,10 +377,6 @@
/* /*
* struct * struct
*/ */
struct regval_list {
unsigned char reg_num;
unsigned char value;
};
struct ov772x_color_format { struct ov772x_color_format {
enum v4l2_mbus_pixelcode code; enum v4l2_mbus_pixelcode code;
...@@ -403,10 +389,8 @@ struct ov772x_color_format { ...@@ -403,10 +389,8 @@ struct ov772x_color_format {
struct ov772x_win_size { struct ov772x_win_size {
char *name; char *name;
__u32 width;
__u32 height;
unsigned char com7_bit; unsigned char com7_bit;
const struct regval_list *regs; struct v4l2_rect rect;
}; };
struct ov772x_priv { struct ov772x_priv {
...@@ -422,31 +406,6 @@ struct ov772x_priv { ...@@ -422,31 +406,6 @@ struct ov772x_priv {
unsigned short band_filter; unsigned short band_filter;
}; };
#define ENDMARKER { 0xff, 0xff }
/*
* register setting for window size
*/
static const struct regval_list ov772x_qvga_regs[] = {
{ HSTART, HST_QVGA },
{ HSIZE, HSZ_QVGA },
{ VSTART, VST_QVGA },
{ VSIZE, VSZ_QVGA },
{ HOUTSIZE, HOSZ_QVGA },
{ VOUTSIZE, VOSZ_QVGA },
ENDMARKER,
};
static const struct regval_list ov772x_vga_regs[] = {
{ HSTART, HST_VGA },
{ HSIZE, HSZ_VGA },
{ VSTART, VST_VGA },
{ VSIZE, VSZ_VGA },
{ HOUTSIZE, HOSZ_VGA },
{ VOUTSIZE, VOSZ_VGA },
ENDMARKER,
};
/* /*
* supported color format list * supported color format list
*/ */
...@@ -525,26 +484,26 @@ static const struct ov772x_color_format ov772x_cfmts[] = { ...@@ -525,26 +484,26 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
/* /*
* window size list * window size list
*/ */
#define VGA_WIDTH 640
#define VGA_HEIGHT 480
#define QVGA_WIDTH 320
#define QVGA_HEIGHT 240
#define MAX_WIDTH VGA_WIDTH
#define MAX_HEIGHT VGA_HEIGHT
static const struct ov772x_win_size ov772x_win_sizes[] = { static const struct ov772x_win_size ov772x_win_sizes[] = {
{ {
.name = "VGA", .name = "VGA",
.com7_bit = SLCT_VGA,
.rect = {
.left = 140,
.top = 14,
.width = VGA_WIDTH, .width = VGA_WIDTH,
.height = VGA_HEIGHT, .height = VGA_HEIGHT,
.com7_bit = SLCT_VGA, },
.regs = ov772x_vga_regs,
}, { }, {
.name = "QVGA", .name = "QVGA",
.com7_bit = SLCT_QVGA,
.rect = {
.left = 252,
.top = 6,
.width = QVGA_WIDTH, .width = QVGA_WIDTH,
.height = QVGA_HEIGHT, .height = QVGA_HEIGHT,
.com7_bit = SLCT_QVGA, },
.regs = ov772x_qvga_regs,
}, },
}; };
...@@ -567,18 +526,6 @@ static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value) ...@@ -567,18 +526,6 @@ static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value)
return i2c_smbus_write_byte_data(client, addr, value); return i2c_smbus_write_byte_data(client, addr, value);
} }
static int ov772x_write_array(struct i2c_client *client,
const struct regval_list *vals)
{
while (vals->reg_num != 0xff) {
int ret = ov772x_write(client, vals->reg_num, vals->value);
if (ret < 0)
return ret;
vals++;
}
return 0;
}
static int ov772x_mask_set(struct i2c_client *client, u8 command, u8 mask, static int ov772x_mask_set(struct i2c_client *client, u8 command, u8 mask,
u8 set) u8 set)
{ {
...@@ -726,8 +673,8 @@ static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) ...@@ -726,8 +673,8 @@ static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
unsigned int i; unsigned int i;
for (i = 0; i < ARRAY_SIZE(ov772x_win_sizes); ++i) { for (i = 0; i < ARRAY_SIZE(ov772x_win_sizes); ++i) {
u32 diff = abs(width - ov772x_win_sizes[i].width) u32 diff = abs(width - ov772x_win_sizes[i].rect.width)
+ abs(height - ov772x_win_sizes[i].height); + abs(height - ov772x_win_sizes[i].rect.height);
if (diff < best_diff) { if (diff < best_diff) {
best_diff = diff; best_diff = diff;
win = &ov772x_win_sizes[i]; win = &ov772x_win_sizes[i];
...@@ -817,10 +764,35 @@ static int ov772x_set_params(struct ov772x_priv *priv, ...@@ -817,10 +764,35 @@ static int ov772x_set_params(struct ov772x_priv *priv,
goto ov772x_set_fmt_error; goto ov772x_set_fmt_error;
} }
/* /* Format and window size */
* set size format ret = ov772x_write(client, HSTART, win->rect.left >> 2);
*/ if (ret < 0)
ret = ov772x_write_array(client, win->regs); goto ov772x_set_fmt_error;
ret = ov772x_write(client, HSIZE, win->rect.width >> 2);
if (ret < 0)
goto ov772x_set_fmt_error;
ret = ov772x_write(client, VSTART, win->rect.top >> 1);
if (ret < 0)
goto ov772x_set_fmt_error;
ret = ov772x_write(client, VSIZE, win->rect.height >> 1);
if (ret < 0)
goto ov772x_set_fmt_error;
ret = ov772x_write(client, HOUTSIZE, win->rect.width >> 2);
if (ret < 0)
goto ov772x_set_fmt_error;
ret = ov772x_write(client, VOUTSIZE, win->rect.height >> 1);
if (ret < 0)
goto ov772x_set_fmt_error;
ret = ov772x_write(client, HREF,
((win->rect.top & 1) << HREF_VSTART_SHIFT) |
((win->rect.left & 3) << HREF_HSTART_SHIFT) |
((win->rect.height & 1) << HREF_VSIZE_SHIFT) |
((win->rect.width & 3) << HREF_HSIZE_SHIFT));
if (ret < 0)
goto ov772x_set_fmt_error;
ret = ov772x_write(client, EXHCH,
((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) |
((win->rect.width & 3) << EXHCH_HSIZE_SHIFT));
if (ret < 0) if (ret < 0)
goto ov772x_set_fmt_error; goto ov772x_set_fmt_error;
...@@ -901,8 +873,8 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) ...@@ -901,8 +873,8 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{ {
a->bounds.left = 0; a->bounds.left = 0;
a->bounds.top = 0; a->bounds.top = 0;
a->bounds.width = VGA_WIDTH; a->bounds.width = OV772X_MAX_WIDTH;
a->bounds.height = VGA_HEIGHT; a->bounds.height = OV772X_MAX_HEIGHT;
a->defrect = a->bounds; a->defrect = a->bounds;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
a->pixelaspect.numerator = 1; a->pixelaspect.numerator = 1;
...@@ -916,8 +888,8 @@ static int ov772x_g_fmt(struct v4l2_subdev *sd, ...@@ -916,8 +888,8 @@ static int ov772x_g_fmt(struct v4l2_subdev *sd,
{ {
struct ov772x_priv *priv = to_ov772x(sd); struct ov772x_priv *priv = to_ov772x(sd);
mf->width = priv->win->width; mf->width = priv->win->rect.width;
mf->height = priv->win->height; mf->height = priv->win->rect.height;
mf->code = priv->cfmt->code; mf->code = priv->cfmt->code;
mf->colorspace = priv->cfmt->colorspace; mf->colorspace = priv->cfmt->colorspace;
mf->field = V4L2_FIELD_NONE; mf->field = V4L2_FIELD_NONE;
...@@ -942,8 +914,8 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) ...@@ -942,8 +914,8 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
priv->cfmt = cfmt; priv->cfmt = cfmt;
mf->code = cfmt->code; mf->code = cfmt->code;
mf->width = win->width; mf->width = win->rect.width;
mf->height = win->height; mf->height = win->rect.height;
mf->field = V4L2_FIELD_NONE; mf->field = V4L2_FIELD_NONE;
mf->colorspace = cfmt->colorspace; mf->colorspace = cfmt->colorspace;
...@@ -959,8 +931,8 @@ static int ov772x_try_fmt(struct v4l2_subdev *sd, ...@@ -959,8 +931,8 @@ static int ov772x_try_fmt(struct v4l2_subdev *sd,
ov772x_select_params(mf, &cfmt, &win); ov772x_select_params(mf, &cfmt, &win);
mf->code = cfmt->code; mf->code = cfmt->code;
mf->width = win->width; mf->width = win->rect.width;
mf->height = win->height; mf->height = win->rect.height;
mf->field = V4L2_FIELD_NONE; mf->field = V4L2_FIELD_NONE;
mf->colorspace = cfmt->colorspace; mf->colorspace = cfmt->colorspace;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment