diff options
author | Antti Palosaari <crope@iki.fi> | 2014-02-07 05:55:57 (GMT) |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-03-14 08:25:36 (GMT) |
commit | ecfb7ca3c8c48e90f2918a72e8ed7a2f989f2635 (patch) | |
tree | 804a6f66addc8d3a921e4bc90cd12225acb2b685 /drivers/media | |
parent | 0ed0b22dc594a533a959ed8995e69e2275af40d9 (diff) | |
download | linux-ecfb7ca3c8c48e90f2918a72e8ed7a2f989f2635.tar.xz |
[media] e4000: implement PLL lock v4l control
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>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/tuners/e4000.c | 53 | ||||
-rw-r--r-- | drivers/media/tuners/e4000_priv.h | 2 |
2 files changed, 54 insertions, 1 deletions
diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index ae52a1f..ed2f635 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -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"); diff --git a/drivers/media/tuners/e4000_priv.h b/drivers/media/tuners/e4000_priv.h index e2ad54f..3ddd980 100644 --- a/drivers/media/tuners/e4000_priv.h +++ b/drivers/media/tuners/e4000_priv.h @@ -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 { |