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.kunin...@renesas.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to