V4L/DVB (13654): tw9910: Tri-state pins when idle
authorKuninori Morimoto <morimoto.kuninori@renesas.com>
Fri, 11 Dec 2009 14:34:50 +0000 (11:34 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 16 Dec 2009 11:27:23 +0000 (09:27 -0200)
Tri-state all pins when not streaming to save power.

Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/tw9910.c

index 3d8a45f0eb2af4049a87d507d97dff740b010304..80b214efb24ea5fcaeee25fc2a3e139186ba0054 100644 (file)
                         /* 1 : non-auto */
 #define VSCTL       0x08 /* 1 : Vertical out ctrl by DVALID */
                         /* 0 : Vertical out ctrl by HACTIVE and DVALID */
-#define OEN         0x04 /* Output Enable together with TRI_SEL. */
+#define OEN_TRI_SEL_MASK       0x07
+#define OEN_TRI_SEL_ALL_ON     0x00 /* Enable output for Rev0/Rev1 */
+#define OEN_TRI_SEL_ALL_OFF_r0 0x06 /* All tri-stated for Rev0 */
+#define OEN_TRI_SEL_ALL_OFF_r1 0x07 /* All tri-stated for Rev1 */
 
 /* OUTCTR1 */
 #define VSP_LO      0x00 /* 0 : VS pin output polarity is active low */
@@ -236,7 +239,6 @@ struct tw9910_priv {
 
 static const struct regval_list tw9910_default_regs[] =
 {
-       { OPFORM,  0x00 },
        { OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC },
        ENDMARKER,
 };
@@ -519,20 +521,35 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
        struct i2c_client *client = sd->priv;
        struct tw9910_priv *priv = to_tw9910(client);
 
-       if (!enable)
-               return 0;
+       u8 val;
 
-       if (!priv->scale) {
-               dev_err(&client->dev, "norm select error\n");
-               return -EPERM;
-       }
+       if (!enable) {
+               switch (priv->revision) {
+               case 0:
+                       val = OEN_TRI_SEL_ALL_OFF_r0;
+                       break;
+               case 1:
+                       val = OEN_TRI_SEL_ALL_OFF_r1;
+                       break;
+               default:
+                       dev_err(&client->dev, "un-supported revision\n");
+                       return -EINVAL;
+               }
+       } else {
+               val = OEN_TRI_SEL_ALL_ON;
 
-       dev_dbg(&client->dev, "%s %dx%d\n",
-                priv->scale->name,
-                priv->scale->width,
-                priv->scale->height);
+               if (!priv->scale) {
+                       dev_err(&client->dev, "norm select error\n");
+                       return -EPERM;
+               }
 
-       return 0;
+               dev_dbg(&client->dev, "%s %dx%d\n",
+                       priv->scale->name,
+                       priv->scale->width,
+                       priv->scale->height);
+       }
+
+       return tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val);
 }
 
 static int tw9910_set_bus_param(struct soc_camera_device *icd,