tw9910 can select output pin width and vs/hs pin feature. This patch add new flags definition to control it. Signed-off-by: Kuninori Morimoto <morimoto.kuninori@xxxxxxxxxxx> --- drivers/media/video/tw9910.c | 72 ++++++++++++++++-------------------------- include/media/tw9910.h | 21 +++++++++++- 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 8bda689..bdabc9a 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -201,12 +201,6 @@ /* * structure */ - -struct regval_list { - unsigned char reg_num; - unsigned char value; -}; - struct tw9910_scale_ctrl { char *name; unsigned short width; @@ -229,18 +223,6 @@ struct tw9910_priv { int rev; }; -/* - * register settings - */ - -#define ENDMARKER { 0xff, 0xff } - -static const struct regval_list tw9910_default_regs[] = -{ - { OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC }, - ENDMARKER, -}; - static const struct soc_camera_data_format tw9910_color_fmt[] = { { .name = "VYUY", @@ -442,20 +424,6 @@ static int tw9910_set_hsync(struct i2c_client *client, return ret; } -static int tw9910_write_array(struct i2c_client *client, - const struct regval_list *vals) -{ - while (vals->reg_num != 0xff) { - int ret = i2c_smbus_write_byte_data(client, - vals->reg_num, - vals->value); - if (ret < 0) - return ret; - vals++; - } - return 0; -} - static int tw9910_mask_set(struct i2c_client *client, u8 command, u8 mask, u8 set) { @@ -469,6 +437,24 @@ static int tw9910_mask_set(struct i2c_client *client, u8 command, return i2c_smbus_write_byte_data(client, command, val); } +static int tw9910_set_outputcontrol(struct i2c_client *client) +{ + struct tw9910_priv *priv = to_tw9910(client); + u32 flags = priv->info->flags; + u8 val = 0; + + if (flags & TW9910_FLG_VS_ACTIVE_HIGH) + val |= (1 << 7); + + if (flags & TW9910_FLG_HS_ACTIVE_HIGH) + val |= (1 << 3); + + val |= ((flags & TW9910_FLG_VS_MASK) >> TW9910_FLG_VS_SHIFT) << 4; + val |= ((flags & TW9910_FLG_HS_MASK) >> TW9910_FLG_HS_SHIFT) << 0; + + return tw9910_mask_set(client, OUTCTR1, 0xff, val); +} + static void tw9910_reset(struct i2c_client *client) { i2c_smbus_write_byte_data(client, ACNTL1, SRESET); @@ -513,7 +499,7 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) { struct i2c_client *client = sd->priv; struct tw9910_priv *priv = to_tw9910(client); - u8 val; + u8 val = OEN; if (!enable) { switch (priv->rev) { @@ -556,7 +542,12 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) struct soc_camera_link *icl = to_soc_camera_link(icd); unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; + SOCAM_DATA_ACTIVE_HIGH; + + if (TW9910_FLG_DATAWIDTH_16 & priv->info->flags) + flags |= SOCAM_DATAWIDTH_16; + else + flags |= SOCAM_DATAWIDTH_8; return soc_camera_apply_sensor_flags(icl, flags); } @@ -648,7 +639,7 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) * reset hardware */ tw9910_reset(client); - ret = tw9910_write_array(client, tw9910_default_regs); + ret = tw9910_set_outputcontrol(client); if (ret < 0) goto tw9910_set_fmt_error; @@ -656,7 +647,7 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) * set bus width */ val = 0x00; - if (SOCAM_DATAWIDTH_16 == priv->info->buswidth) + if (TW9910_FLG_DATAWIDTH_16 & priv->info->flags) val = LEN; ret = tw9910_mask_set(client, OPFORM, LEN, val); @@ -888,15 +879,6 @@ static int tw9910_video_probe(struct soc_camera_device *icd, to_soc_camera_host(icd->dev.parent)->nr != icd->iface) return -ENODEV; - /* - * tw9910 only use 8 or 16 bit bus width - */ - if (SOCAM_DATAWIDTH_16 != priv->info->buswidth && - SOCAM_DATAWIDTH_8 != priv->info->buswidth) { - dev_err(&client->dev, "bus width error\n"); - return -ENODEV; - } - icd->formats = tw9910_color_fmt; icd->num_formats = ARRAY_SIZE(tw9910_color_fmt); diff --git a/include/media/tw9910.h b/include/media/tw9910.h index 6ddb654..494ac53 100644 --- a/include/media/tw9910.h +++ b/include/media/tw9910.h @@ -18,6 +18,25 @@ #include <media/soc_camera.h> +#define TW9910_FLG_DATAWIDTH_16 (1 << 0) /* default 8 */ +#define TW9910_FLG_VS_ACTIVE_HIGH (1 << 1) /* default Low */ +#define TW9910_FLG_HS_ACTIVE_HIGH (1 << 2) /* default Low */ + +#define TW9910_FLG_VS_SHIFT (4) +#define TW9910_FLG_VS_MASK (0xF << TW9910_FLG_VS_SHIFT) +#define TW9910_FLG_VS_VSYNC (0 << TW9910_FLG_VS_SHIFT) +#define TW9910_FLG_VS_VACT (1 << TW9910_FLG_VS_SHIFT) +#define TW9910_FLG_VS_FIELD (2 << TW9910_FLG_VS_SHIFT) +#define TW9910_FLG_VS_VVALID (3 << TW9910_FLG_VS_SHIFT) + +#define TW9910_FLG_HS_SHIFT (8) +#define TW9910_FLG_HS_MASK (0xF << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_HACT (0 << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_HSYNC (1 << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_DVALID (2 << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_HLOCK (3 << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_ASYNCW (4 << TW9910_FLG_HS_SHIFT) + enum tw9910_mpout_pin { TW9910_MPO_VLOSS, TW9910_MPO_HLOCK, @@ -30,7 +49,7 @@ enum tw9910_mpout_pin { }; struct tw9910_video_info { - unsigned long buswidth; + u32 flags; enum tw9910_mpout_pin mpout; struct soc_camera_link link; u16 start_offset; -- 1.6.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html