[media] e4000: implement PLL lock v4l control
authorAntti Palosaari <crope@iki.fi>
Fri, 7 Feb 2014 05:55:57 +0000 (02:55 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Fri, 14 Mar 2014 08:25:36 +0000 (05:25 -0300)
Implement PLL lock control to get PLL lock flag status from tuner
synthesizer.

Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/tuners/e4000.c
drivers/media/tuners/e4000_priv.h

index ae52a1f4bb13d1b60d4cb93ef26dc42afc9781ef..ed2f63580fd7b4f1a077f8f503c4a07d9fefca8b 100644 (file)
@@ -181,6 +181,8 @@ static int e4000_init(struct dvb_frontend *fe)
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 0);
 
+       priv->active = true;
+
        return 0;
 err:
        if (fe->ops.i2c_gate_ctrl)
@@ -197,6 +199,8 @@ static int e4000_sleep(struct dvb_frontend *fe)
 
        dev_dbg(&priv->client->dev, "%s:\n", __func__);
 
+       priv->active = false;
+
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 1);
 
@@ -512,6 +516,50 @@ err:
        return ret;
 }
 
+static int e4000_pll_lock(struct dvb_frontend *fe)
+{
+       struct e4000_priv *priv = fe->tuner_priv;
+       int ret;
+       u8 u8tmp;
+
+       if (priv->active == false)
+               return 0;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       ret = e4000_rd_reg(priv, 0x07, &u8tmp);
+       if (ret)
+               goto err;
+
+       priv->pll_lock->val = (u8tmp & 0x01);
+err:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       if (ret)
+               dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int e4000_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct e4000_priv *priv =
+                       container_of(ctrl->handler, struct e4000_priv, hdl);
+       int ret;
+
+       switch (ctrl->id) {
+       case  V4L2_CID_RF_TUNER_PLL_LOCK:
+               ret = e4000_pll_lock(priv->fe);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
 static int e4000_s_ctrl(struct v4l2_ctrl *ctrl)
 {
        struct e4000_priv *priv =
@@ -550,6 +598,7 @@ static int e4000_s_ctrl(struct v4l2_ctrl *ctrl)
 }
 
 static const struct v4l2_ctrl_ops e4000_ctrl_ops = {
+       .g_volatile_ctrl = e4000_g_volatile_ctrl,
        .s_ctrl = e4000_s_ctrl,
 };
 
@@ -613,7 +662,7 @@ static int e4000_probe(struct i2c_client *client,
                goto err;
 
        /* Register controls */
-       v4l2_ctrl_handler_init(&priv->hdl, 8);
+       v4l2_ctrl_handler_init(&priv->hdl, 9);
        priv->bandwidth_auto = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops,
                        V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
        priv->bandwidth = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops,
@@ -634,6 +683,8 @@ static int e4000_probe(struct i2c_client *client,
        priv->if_gain = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops,
                        V4L2_CID_RF_TUNER_IF_GAIN, 0, 54, 1, 0);
        v4l2_ctrl_auto_cluster(2, &priv->if_gain_auto, 0, false);
+       priv->pll_lock = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_PLL_LOCK,  0, 1, 1, 0);
        if (priv->hdl.error) {
                ret = priv->hdl.error;
                dev_err(&priv->client->dev, "Could not initialize controls\n");
index e2ad54f522801b0ccfa0a3feb404310508121cd9..3ddd9802ff3c0770663e3a1903d64a552d989128 100644 (file)
@@ -30,6 +30,7 @@ struct e4000_priv {
        u32 clock;
        struct dvb_frontend *fe;
        struct v4l2_subdev sd;
+       bool active;
 
        /* Controls */
        struct v4l2_ctrl_handler hdl;
@@ -41,6 +42,7 @@ struct e4000_priv {
        struct v4l2_ctrl *mixer_gain;
        struct v4l2_ctrl *if_gain_auto;
        struct v4l2_ctrl *if_gain;
+       struct v4l2_ctrl *pll_lock;
 };
 
 struct e4000_pll {