diff options
author | Antti Palosaari <crope@iki.fi> | 2014-02-07 00:55:57 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-03-14 04:25:36 -0400 |
commit | ecfb7ca3c8c48e90f2918a72e8ed7a2f989f2635 (patch) | |
tree | 804a6f66addc8d3a921e4bc90cd12225acb2b685 /drivers/media/tuners/e4000.c | |
parent | 0ed0b22dc594a533a959ed8995e69e2275af40d9 (diff) |
[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/tuners/e4000.c')
-rw-r--r-- | drivers/media/tuners/e4000.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index ae52a1f4bb13..ed2f63580fd7 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) | |||
181 | if (fe->ops.i2c_gate_ctrl) | 181 | if (fe->ops.i2c_gate_ctrl) |
182 | fe->ops.i2c_gate_ctrl(fe, 0); | 182 | fe->ops.i2c_gate_ctrl(fe, 0); |
183 | 183 | ||
184 | priv->active = true; | ||
185 | |||
184 | return 0; | 186 | return 0; |
185 | err: | 187 | err: |
186 | if (fe->ops.i2c_gate_ctrl) | 188 | if (fe->ops.i2c_gate_ctrl) |
@@ -197,6 +199,8 @@ static int e4000_sleep(struct dvb_frontend *fe) | |||
197 | 199 | ||
198 | dev_dbg(&priv->client->dev, "%s:\n", __func__); | 200 | dev_dbg(&priv->client->dev, "%s:\n", __func__); |
199 | 201 | ||
202 | priv->active = false; | ||
203 | |||
200 | if (fe->ops.i2c_gate_ctrl) | 204 | if (fe->ops.i2c_gate_ctrl) |
201 | fe->ops.i2c_gate_ctrl(fe, 1); | 205 | fe->ops.i2c_gate_ctrl(fe, 1); |
202 | 206 | ||
@@ -512,6 +516,50 @@ err: | |||
512 | return ret; | 516 | return ret; |
513 | } | 517 | } |
514 | 518 | ||
519 | static int e4000_pll_lock(struct dvb_frontend *fe) | ||
520 | { | ||
521 | struct e4000_priv *priv = fe->tuner_priv; | ||
522 | int ret; | ||
523 | u8 u8tmp; | ||
524 | |||
525 | if (priv->active == false) | ||
526 | return 0; | ||
527 | |||
528 | if (fe->ops.i2c_gate_ctrl) | ||
529 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
530 | |||
531 | ret = e4000_rd_reg(priv, 0x07, &u8tmp); | ||
532 | if (ret) | ||
533 | goto err; | ||
534 | |||
535 | priv->pll_lock->val = (u8tmp & 0x01); | ||
536 | err: | ||
537 | if (fe->ops.i2c_gate_ctrl) | ||
538 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
539 | |||
540 | if (ret) | ||
541 | dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret); | ||
542 | |||
543 | return ret; | ||
544 | } | ||
545 | |||
546 | static int e4000_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | ||
547 | { | ||
548 | struct e4000_priv *priv = | ||
549 | container_of(ctrl->handler, struct e4000_priv, hdl); | ||
550 | int ret; | ||
551 | |||
552 | switch (ctrl->id) { | ||
553 | case V4L2_CID_RF_TUNER_PLL_LOCK: | ||
554 | ret = e4000_pll_lock(priv->fe); | ||
555 | break; | ||
556 | default: | ||
557 | ret = -EINVAL; | ||
558 | } | ||
559 | |||
560 | return ret; | ||
561 | } | ||
562 | |||
515 | static int e4000_s_ctrl(struct v4l2_ctrl *ctrl) | 563 | static int e4000_s_ctrl(struct v4l2_ctrl *ctrl) |
516 | { | 564 | { |
517 | struct e4000_priv *priv = | 565 | struct e4000_priv *priv = |
@@ -550,6 +598,7 @@ static int e4000_s_ctrl(struct v4l2_ctrl *ctrl) | |||
550 | } | 598 | } |
551 | 599 | ||
552 | static const struct v4l2_ctrl_ops e4000_ctrl_ops = { | 600 | static const struct v4l2_ctrl_ops e4000_ctrl_ops = { |
601 | .g_volatile_ctrl = e4000_g_volatile_ctrl, | ||
553 | .s_ctrl = e4000_s_ctrl, | 602 | .s_ctrl = e4000_s_ctrl, |
554 | }; | 603 | }; |
555 | 604 | ||
@@ -613,7 +662,7 @@ static int e4000_probe(struct i2c_client *client, | |||
613 | goto err; | 662 | goto err; |
614 | 663 | ||
615 | /* Register controls */ | 664 | /* Register controls */ |
616 | v4l2_ctrl_handler_init(&priv->hdl, 8); | 665 | v4l2_ctrl_handler_init(&priv->hdl, 9); |
617 | priv->bandwidth_auto = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops, | 666 | priv->bandwidth_auto = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops, |
618 | V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1); | 667 | V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1); |
619 | priv->bandwidth = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops, | 668 | priv->bandwidth = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops, |
@@ -634,6 +683,8 @@ static int e4000_probe(struct i2c_client *client, | |||
634 | priv->if_gain = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops, | 683 | priv->if_gain = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops, |
635 | V4L2_CID_RF_TUNER_IF_GAIN, 0, 54, 1, 0); | 684 | V4L2_CID_RF_TUNER_IF_GAIN, 0, 54, 1, 0); |
636 | v4l2_ctrl_auto_cluster(2, &priv->if_gain_auto, 0, false); | 685 | v4l2_ctrl_auto_cluster(2, &priv->if_gain_auto, 0, false); |
686 | priv->pll_lock = v4l2_ctrl_new_std(&priv->hdl, &e4000_ctrl_ops, | ||
687 | V4L2_CID_RF_TUNER_PLL_LOCK, 0, 1, 1, 0); | ||
637 | if (priv->hdl.error) { | 688 | if (priv->hdl.error) { |
638 | ret = priv->hdl.error; | 689 | ret = priv->hdl.error; |
639 | dev_err(&priv->client->dev, "Could not initialize controls\n"); | 690 | dev_err(&priv->client->dev, "Could not initialize controls\n"); |