diff options
author | Ondrej Zary <linux@rainbow-software.org> | 2013-02-03 20:47:38 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-08 06:00:47 -0400 |
commit | 2f719f7a9aa599bc9e1516190336a4ac5c59b18a (patch) | |
tree | 623c4a57a02907f7f6ae42903cb7ab6f2a279a1c /drivers | |
parent | 48a8a03b5806179f12dd6994a6957f797c13675f (diff) |
[media] tda8290: Allow disabling I2C gate
Allow disabling I2C gate handling by external configuration.
This is required by cards that have all devices on a single I2C bus,
like AverMedia A706.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/tuners/tda8290.c | 49 | ||||
-rw-r--r-- | drivers/media/tuners/tda8290.h | 1 |
2 files changed, 30 insertions, 20 deletions
diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c index 8c4852114eeb..a2b7a9fbd344 100644 --- a/drivers/media/tuners/tda8290.c +++ b/drivers/media/tuners/tda8290.c | |||
@@ -233,7 +233,8 @@ static void tda8290_set_params(struct dvb_frontend *fe, | |||
233 | } | 233 | } |
234 | 234 | ||
235 | 235 | ||
236 | tda8290_i2c_bridge(fe, 1); | 236 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
237 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 1); | ||
237 | 238 | ||
238 | if (fe->ops.tuner_ops.set_analog_params) | 239 | if (fe->ops.tuner_ops.set_analog_params) |
239 | fe->ops.tuner_ops.set_analog_params(fe, params); | 240 | fe->ops.tuner_ops.set_analog_params(fe, params); |
@@ -302,7 +303,8 @@ static void tda8290_set_params(struct dvb_frontend *fe, | |||
302 | } | 303 | } |
303 | } | 304 | } |
304 | 305 | ||
305 | tda8290_i2c_bridge(fe, 0); | 306 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
307 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 0); | ||
306 | tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2); | 308 | tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2); |
307 | } | 309 | } |
308 | 310 | ||
@@ -424,7 +426,8 @@ static void tda8295_set_params(struct dvb_frontend *fe, | |||
424 | tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2); | 426 | tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2); |
425 | msleep(20); | 427 | msleep(20); |
426 | 428 | ||
427 | tda8295_i2c_bridge(fe, 1); | 429 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
430 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 1); | ||
428 | 431 | ||
429 | if (fe->ops.tuner_ops.set_analog_params) | 432 | if (fe->ops.tuner_ops.set_analog_params) |
430 | fe->ops.tuner_ops.set_analog_params(fe, params); | 433 | fe->ops.tuner_ops.set_analog_params(fe, params); |
@@ -437,7 +440,8 @@ static void tda8295_set_params(struct dvb_frontend *fe, | |||
437 | else | 440 | else |
438 | tuner_dbg("tda8295 not locked, no signal?\n"); | 441 | tuner_dbg("tda8295 not locked, no signal?\n"); |
439 | 442 | ||
440 | tda8295_i2c_bridge(fe, 0); | 443 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
444 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 0); | ||
441 | } | 445 | } |
442 | 446 | ||
443 | /*---------------------------------------------------------------------*/ | 447 | /*---------------------------------------------------------------------*/ |
@@ -465,11 +469,13 @@ static void tda8290_standby(struct dvb_frontend *fe) | |||
465 | unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; | 469 | unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; |
466 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; | 470 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; |
467 | 471 | ||
468 | tda8290_i2c_bridge(fe, 1); | 472 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
473 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 1); | ||
469 | if (priv->ver & TDA8275A) | 474 | if (priv->ver & TDA8275A) |
470 | cb1[1] = 0x90; | 475 | cb1[1] = 0x90; |
471 | i2c_transfer(priv->i2c_props.adap, &msg, 1); | 476 | i2c_transfer(priv->i2c_props.adap, &msg, 1); |
472 | tda8290_i2c_bridge(fe, 0); | 477 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
478 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 0); | ||
473 | tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2); | 479 | tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2); |
474 | tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2); | 480 | tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2); |
475 | } | 481 | } |
@@ -537,9 +543,11 @@ static void tda8290_init_tuner(struct dvb_frontend *fe) | |||
537 | if (priv->ver & TDA8275A) | 543 | if (priv->ver & TDA8275A) |
538 | msg.buf = tda8275a_init; | 544 | msg.buf = tda8275a_init; |
539 | 545 | ||
540 | tda8290_i2c_bridge(fe, 1); | 546 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
547 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 1); | ||
541 | i2c_transfer(priv->i2c_props.adap, &msg, 1); | 548 | i2c_transfer(priv->i2c_props.adap, &msg, 1); |
542 | tda8290_i2c_bridge(fe, 0); | 549 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
550 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 0); | ||
543 | } | 551 | } |
544 | 552 | ||
545 | /*---------------------------------------------------------------------*/ | 553 | /*---------------------------------------------------------------------*/ |
@@ -565,19 +573,13 @@ static struct tda18271_config tda829x_tda18271_config = { | |||
565 | static int tda829x_find_tuner(struct dvb_frontend *fe) | 573 | static int tda829x_find_tuner(struct dvb_frontend *fe) |
566 | { | 574 | { |
567 | struct tda8290_priv *priv = fe->analog_demod_priv; | 575 | struct tda8290_priv *priv = fe->analog_demod_priv; |
568 | struct analog_demod_ops *analog_ops = &fe->ops.analog_ops; | ||
569 | int i, ret, tuners_found; | 576 | int i, ret, tuners_found; |
570 | u32 tuner_addrs; | 577 | u32 tuner_addrs; |
571 | u8 data; | 578 | u8 data; |
572 | struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; | 579 | struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; |
573 | 580 | ||
574 | if (!analog_ops->i2c_gate_ctrl) { | 581 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
575 | printk(KERN_ERR "tda8290: no gate control were provided!\n"); | 582 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 1); |
576 | |||
577 | return -EINVAL; | ||
578 | } | ||
579 | |||
580 | analog_ops->i2c_gate_ctrl(fe, 1); | ||
581 | 583 | ||
582 | /* probe for tuner chip */ | 584 | /* probe for tuner chip */ |
583 | tuners_found = 0; | 585 | tuners_found = 0; |
@@ -595,7 +597,8 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) | |||
595 | give a response now | 597 | give a response now |
596 | */ | 598 | */ |
597 | 599 | ||
598 | analog_ops->i2c_gate_ctrl(fe, 0); | 600 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
601 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 0); | ||
599 | 602 | ||
600 | if (tuners_found > 1) | 603 | if (tuners_found > 1) |
601 | for (i = 0; i < tuners_found; i++) { | 604 | for (i = 0; i < tuners_found; i++) { |
@@ -618,12 +621,14 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) | |||
618 | priv->tda827x_addr = tuner_addrs; | 621 | priv->tda827x_addr = tuner_addrs; |
619 | msg.addr = tuner_addrs; | 622 | msg.addr = tuner_addrs; |
620 | 623 | ||
621 | analog_ops->i2c_gate_ctrl(fe, 1); | 624 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
625 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 1); | ||
622 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); | 626 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); |
623 | 627 | ||
624 | if (ret != 1) { | 628 | if (ret != 1) { |
625 | tuner_warn("tuner access failed!\n"); | 629 | tuner_warn("tuner access failed!\n"); |
626 | analog_ops->i2c_gate_ctrl(fe, 0); | 630 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
631 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 0); | ||
627 | return -EREMOTEIO; | 632 | return -EREMOTEIO; |
628 | } | 633 | } |
629 | 634 | ||
@@ -648,7 +653,8 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) | |||
648 | if (fe->ops.tuner_ops.sleep) | 653 | if (fe->ops.tuner_ops.sleep) |
649 | fe->ops.tuner_ops.sleep(fe); | 654 | fe->ops.tuner_ops.sleep(fe); |
650 | 655 | ||
651 | analog_ops->i2c_gate_ctrl(fe, 0); | 656 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
657 | fe->ops.analog_ops.i2c_gate_ctrl(fe, 0); | ||
652 | 658 | ||
653 | return 0; | 659 | return 0; |
654 | } | 660 | } |
@@ -755,6 +761,9 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | |||
755 | sizeof(struct analog_demod_ops)); | 761 | sizeof(struct analog_demod_ops)); |
756 | } | 762 | } |
757 | 763 | ||
764 | if (cfg && cfg->no_i2c_gate) | ||
765 | fe->ops.analog_ops.i2c_gate_ctrl = NULL; | ||
766 | |||
758 | if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) { | 767 | if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) { |
759 | tda8295_power(fe, 1); | 768 | tda8295_power(fe, 1); |
760 | if (tda829x_find_tuner(fe) < 0) | 769 | if (tda829x_find_tuner(fe) < 0) |
diff --git a/drivers/media/tuners/tda8290.h b/drivers/media/tuners/tda8290.h index e12ecbaa35a4..b5b51a947747 100644 --- a/drivers/media/tuners/tda8290.h +++ b/drivers/media/tuners/tda8290.h | |||
@@ -26,6 +26,7 @@ struct tda829x_config { | |||
26 | unsigned int probe_tuner:1; | 26 | unsigned int probe_tuner:1; |
27 | #define TDA829X_PROBE_TUNER 0 | 27 | #define TDA829X_PROBE_TUNER 0 |
28 | #define TDA829X_DONT_PROBE 1 | 28 | #define TDA829X_DONT_PROBE 1 |
29 | unsigned int no_i2c_gate:1; | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TDA8290) | 32 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TDA8290) |