#define SLCT_QVGA 0x40 /* 1 : QVGA */
#define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */
/* RGB output format control */
+#define FMT_MASK 0x0c /* Mask of color format */
#define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */
#define FMT_RGB565 0x04 /* 01 : RGB 565 */
#define FMT_RGB555 0x08 /* 10 : RGB 555 */
#define FMT_RGB444 0x0c /* 11 : RGB 444 */
/* Output format control */
+#define OFMT_MASK 0x03 /* Mask of output format */
#define OFMT_YUV 0x00 /* 00 : YUV */
#define OFMT_P_BRAW 0x01 /* 01 : Processed Bayer RAW */
#define OFMT_RGB 0x02 /* 10 : RGB */
#define GAIN_2x 0x00 /* 000 : 2x */
#define GAIN_4x 0x10 /* 001 : 4x */
#define GAIN_8x 0x20 /* 010 : 8x */
-#define GAIN_16x 0x30 /* 011 : 16x */
+#define GAIN_16x 0x30 /* 011 : 16x */
#define GAIN_32x 0x40 /* 100 : 32x */
#define GAIN_64x 0x50 /* 101 : 64x */
#define GAIN_128x 0x60 /* 110 : 128x */
#define VOSZ_VGA 0xF0
#define VOSZ_QVGA 0x78
-/*
- * bit configure (32 bit)
- * this is used in struct ov772x_color_format :: option
- */
-#define OP_UV 0x00000001
-#define OP_SWAP_RGB 0x00000002
-
/*
* ID
*/
struct ov772x_color_format {
char *name;
__u32 fourcc;
- const struct regval_list *regs;
- unsigned int option;
+ u8 dsp3;
+ u8 com3;
+ u8 com7;
};
struct ov772x_win_size {
#define ENDMARKER { 0xff, 0xff }
-/*
- * register setting for color format
- */
-static const struct regval_list ov772x_RGB555_regs[] = {
- { COM3, 0x00 },
- { COM7, FMT_RGB555 | OFMT_RGB },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_RGB565_regs[] = {
- { COM3, 0x00 },
- { COM7, FMT_RGB565 | OFMT_RGB },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_YYUV_regs[] = {
- { COM3, SWAP_YUV },
- { COM7, OFMT_YUV },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_UVYY_regs[] = {
- { COM3, 0x00 },
- { COM7, OFMT_YUV },
- ENDMARKER,
-};
-
-
/*
* register setting for window size
*/
/*
* color format list
*/
-#define T_YUYV 0
static const struct ov772x_color_format ov772x_cfmts[] = {
- [T_YUYV] = {
+ {
SETFOURCC(YUYV),
- .regs = ov772x_YYUV_regs,
+ .dsp3 = 0x0,
+ .com3 = SWAP_YUV,
+ .com7 = OFMT_YUV,
},
{
SETFOURCC(YVYU),
- .regs = ov772x_YYUV_regs,
- .option = OP_UV,
+ .dsp3 = UV_ON,
+ .com3 = SWAP_YUV,
+ .com7 = OFMT_YUV,
},
{
SETFOURCC(UYVY),
- .regs = ov772x_UVYY_regs,
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = OFMT_YUV,
},
{
SETFOURCC(RGB555),
- .regs = ov772x_RGB555_regs,
- .option = OP_SWAP_RGB,
+ .dsp3 = 0x0,
+ .com3 = SWAP_RGB,
+ .com7 = FMT_RGB555 | OFMT_RGB,
},
{
SETFOURCC(RGB555X),
- .regs = ov772x_RGB555_regs,
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = FMT_RGB555 | OFMT_RGB,
},
{
SETFOURCC(RGB565),
- .regs = ov772x_RGB565_regs,
- .option = OP_SWAP_RGB,
+ .dsp3 = 0x0,
+ .com3 = SWAP_RGB,
+ .com7 = FMT_RGB565 | OFMT_RGB,
},
{
SETFOURCC(RGB565X),
- .regs = ov772x_RGB565_regs,
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = FMT_RGB565 | OFMT_RGB,
},
};
u8 set)
{
s32 val = i2c_smbus_read_byte_data(client, command);
+ if (val < 0)
+ return val;
+
val &= ~mask;
- val |= set;
+ val |= set & mask;
return i2c_smbus_write_byte_data(client, command, val);
}
static int ov772x_start_capture(struct soc_camera_device *icd)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
- int ret;
-
- if (!priv->win)
- priv->win = &ov772x_win_vga;
- if (!priv->fmt)
- priv->fmt = &ov772x_cfmts[T_YUYV];
-
- /*
- * reset hardware
- */
- ov772x_reset(priv->client);
-
- /*
- * set color format
- */
- ret = ov772x_write_array(priv->client, priv->fmt->regs);
- if (ret < 0)
- goto start_end;
-
- /*
- * set size format
- */
- ret = ov772x_write_array(priv->client, priv->win->regs);
- if (ret < 0)
- goto start_end;
-
- /*
- * set COM7 bit ( QVGA or VGA )
- */
- ret = ov772x_mask_set(priv->client,
- COM7, SLCT_MASK, priv->win->com7_bit);
- if (ret < 0)
- goto start_end;
-
- /*
- * set UV setting
- */
- if (priv->fmt->option & OP_UV) {
- ret = ov772x_mask_set(priv->client,
- DSP_CTRL3, UV_MASK, UV_ON);
- if (ret < 0)
- goto start_end;
- }
- /*
- * set SWAP setting
- */
- if (priv->fmt->option & OP_SWAP_RGB) {
- ret = ov772x_mask_set(priv->client,
- COM3, SWAP_MASK, SWAP_RGB);
- if (ret < 0)
- goto start_end;
+ if (!priv->win || !priv->fmt) {
+ dev_err(&icd->dev, "norm or win select error\n");
+ return -EPERM;
}
dev_dbg(&icd->dev,
"format %s, win %s\n", priv->fmt->name, priv->win->name);
-start_end:
- priv->fmt = NULL;
- priv->win = NULL;
-
- return ret;
+ return 0;
}
static int ov772x_stop_capture(struct soc_camera_device *icd)
{
- struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
- ov772x_reset(priv->client);
return 0;
}
struct soc_camera_link *icl = priv->client->dev.platform_data;
unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
- priv->info->buswidth;
+ SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
return soc_camera_apply_sensor_flags(icl, flags);
}
return win;
}
-
static int ov772x_set_fmt(struct soc_camera_device *icd,
__u32 pixfmt,
struct v4l2_rect *rect)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
int ret = -EINVAL;
+ u8 val;
int i;
/*
for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
if (pixfmt == ov772x_cfmts[i].fourcc) {
priv->fmt = ov772x_cfmts + i;
- ret = 0;
break;
}
}
+ if (!priv->fmt)
+ goto ov772x_set_fmt_error;
/*
* select win
*/
priv->win = ov772x_select_win(rect->width, rect->height);
+ /*
+ * reset hardware
+ */
+ ov772x_reset(priv->client);
+
+ /*
+ * set size format
+ */
+ ret = ov772x_write_array(priv->client, priv->win->regs);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ /*
+ * set DSP_CTRL3
+ */
+ val = priv->fmt->dsp3;
+ if (val) {
+ ret = ov772x_mask_set(priv->client,
+ DSP_CTRL3, UV_MASK, val);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ }
+
+ /*
+ * set COM3
+ */
+ val = priv->fmt->com3;
+ ret = ov772x_mask_set(priv->client,
+ COM3, SWAP_MASK, val);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ /*
+ * set COM7
+ */
+ val = priv->win->com7_bit | priv->fmt->com7;
+ ret = ov772x_mask_set(priv->client,
+ COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
+ val);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ return ret;
+
+ov772x_set_fmt_error:
+
+ ov772x_reset(priv->client);
+ priv->win = NULL;
+ priv->fmt = NULL;
+
return ret;
}
i2c_smbus_read_byte_data(priv->client, MIDH),
i2c_smbus_read_byte_data(priv->client, MIDL));
-
return soc_camera_video_start(icd);
}