diff options
-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 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"); |
diff --git a/drivers/media/tuners/e4000_priv.h b/drivers/media/tuners/e4000_priv.h index e2ad54f52280..3ddd9802ff3c 100644 --- a/drivers/media/tuners/e4000_priv.h +++ b/drivers/media/tuners/e4000_priv.h | |||
@@ -30,6 +30,7 @@ struct e4000_priv { | |||
30 | u32 clock; | 30 | u32 clock; |
31 | struct dvb_frontend *fe; | 31 | struct dvb_frontend *fe; |
32 | struct v4l2_subdev sd; | 32 | struct v4l2_subdev sd; |
33 | bool active; | ||
33 | 34 | ||
34 | /* Controls */ | 35 | /* Controls */ |
35 | struct v4l2_ctrl_handler hdl; | 36 | struct v4l2_ctrl_handler hdl; |
@@ -41,6 +42,7 @@ struct e4000_priv { | |||
41 | struct v4l2_ctrl *mixer_gain; | 42 | struct v4l2_ctrl *mixer_gain; |
42 | struct v4l2_ctrl *if_gain_auto; | 43 | struct v4l2_ctrl *if_gain_auto; |
43 | struct v4l2_ctrl *if_gain; | 44 | struct v4l2_ctrl *if_gain; |
45 | struct v4l2_ctrl *pll_lock; | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | struct e4000_pll { | 48 | struct e4000_pll { |