diff options
Diffstat (limited to 'drivers/media/dvb/frontends/au8522_dig.c')
-rw-r--r-- | drivers/media/dvb/frontends/au8522_dig.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index a1fed0fa8ed4..65f6a36dfb21 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c | |||
@@ -84,6 +84,14 @@ static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | |||
84 | 84 | ||
85 | dprintk("%s(%d)\n", __func__, enable); | 85 | dprintk("%s(%d)\n", __func__, enable); |
86 | 86 | ||
87 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
88 | /* We're being asked to manage the gate even though we're | ||
89 | not in digital mode. This can occur if we get switched | ||
90 | over to analog mode before the dvb_frontend kernel thread | ||
91 | has completely shutdown */ | ||
92 | return 0; | ||
93 | } | ||
94 | |||
87 | if (enable) | 95 | if (enable) |
88 | return au8522_writereg(state, 0x106, 1); | 96 | return au8522_writereg(state, 0x106, 1); |
89 | else | 97 | else |
@@ -608,6 +616,13 @@ int au8522_init(struct dvb_frontend *fe) | |||
608 | struct au8522_state *state = fe->demodulator_priv; | 616 | struct au8522_state *state = fe->demodulator_priv; |
609 | dprintk("%s()\n", __func__); | 617 | dprintk("%s()\n", __func__); |
610 | 618 | ||
619 | state->operational_mode = AU8522_DIGITAL_MODE; | ||
620 | |||
621 | /* Clear out any state associated with the digital side of the | ||
622 | chip, so that when it gets powered back up it won't think | ||
623 | that it is already tuned */ | ||
624 | state->current_frequency = 0; | ||
625 | |||
611 | au8522_writereg(state, 0xa4, 1 << 5); | 626 | au8522_writereg(state, 0xa4, 1 << 5); |
612 | 627 | ||
613 | au8522_i2c_gate_ctrl(fe, 1); | 628 | au8522_i2c_gate_ctrl(fe, 1); |
@@ -704,6 +719,15 @@ int au8522_sleep(struct dvb_frontend *fe) | |||
704 | struct au8522_state *state = fe->demodulator_priv; | 719 | struct au8522_state *state = fe->demodulator_priv; |
705 | dprintk("%s()\n", __func__); | 720 | dprintk("%s()\n", __func__); |
706 | 721 | ||
722 | /* Only power down if the digital side is currently using the chip */ | ||
723 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
724 | /* We're not in one of the expected power modes, which means | ||
725 | that the DVB thread is probably telling us to go to sleep | ||
726 | even though the analog frontend has already started using | ||
727 | the chip. So ignore the request */ | ||
728 | return 0; | ||
729 | } | ||
730 | |||
707 | /* turn off led */ | 731 | /* turn off led */ |
708 | au8522_led_ctrl(state, 0); | 732 | au8522_led_ctrl(state, 0); |
709 | 733 | ||
@@ -932,6 +956,8 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config, | |||
932 | /* setup the state */ | 956 | /* setup the state */ |
933 | state->config = config; | 957 | state->config = config; |
934 | state->i2c = i2c; | 958 | state->i2c = i2c; |
959 | state->operational_mode = AU8522_DIGITAL_MODE; | ||
960 | |||
935 | /* create dvb_frontend */ | 961 | /* create dvb_frontend */ |
936 | memcpy(&state->frontend.ops, &au8522_ops, | 962 | memcpy(&state->frontend.ops, &au8522_ops, |
937 | sizeof(struct dvb_frontend_ops)); | 963 | sizeof(struct dvb_frontend_ops)); |