aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
authorAndreas Regel <andreas.regel@gmx.de>2011-01-10 04:36:09 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:31:44 -0400
commit5bd0dc2d8a0db2f2e119ea50d07bf49e5e038f12 (patch)
tree4c4e788ca3627c334be3a5f9091f81a38006a80d /drivers/media/dvb/frontends
parent2c2c441b10644a273ff82a43ec18034ec1dd4c4e (diff)
[media] stv090x: make sleep/wakeup specific to the demod path
The STV0900 features two demodulator paths in one chip. Thus it is not possible to use the generic power off function of the chip when sending one of them to standby. The other path will stop working in that case. The sleep function now switches off functionality specific to the demod path. The global stuff is only switched off, when both paths are in sleep mode. The wakeup function always turns on the global functionality and then works specific to the path. Signed-off-by: Andreas Regel <andreas.regel@gmx.de> Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Manu Abraham <manu@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/stv090x.c211
1 files changed, 185 insertions, 26 deletions
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index dba2c0407fd1..e26bfd765460 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -3846,6 +3846,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3846{ 3846{
3847 struct stv090x_state *state = fe->demodulator_priv; 3847 struct stv090x_state *state = fe->demodulator_priv;
3848 u32 reg; 3848 u32 reg;
3849 u8 full_standby = 0;
3849 3850
3850 if (stv090x_i2c_gate_ctrl(state, 1) < 0) 3851 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3851 goto err; 3852 goto err;
@@ -3858,24 +3859,119 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3858 if (stv090x_i2c_gate_ctrl(state, 0) < 0) 3859 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3859 goto err; 3860 goto err;
3860 3861
3861 dprintk(FE_DEBUG, 1, "Set %s to sleep", 3862 dprintk(FE_DEBUG, 1, "Set %s(%d) to sleep",
3862 state->device == STV0900 ? "STV0900" : "STV0903"); 3863 state->device == STV0900 ? "STV0900" : "STV0903",
3864 state->demod);
3863 3865
3864 reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 3866 mutex_lock(&state->internal->demod_lock);
3865 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
3866 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3867 goto err;
3868 3867
3869 reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3868 switch (state->demod) {
3870 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); 3869 case STV090x_DEMODULATOR_0:
3871 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 3870 /* power off ADC 1 */
3872 goto err; 3871 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3872 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
3873 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
3874 goto err;
3875 /* power off DiSEqC 1 */
3876 reg = stv090x_read_reg(state, STV090x_TSTTNR2);
3877 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
3878 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
3879 goto err;
3880
3881 /* check whether path 2 is already sleeping, that is when
3882 ADC2 is off */
3883 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
3884 if (STV090x_GETFIELD(reg, ADC2_PON_FIELD) == 0)
3885 full_standby = 1;
3886
3887 /* stop clocks */
3888 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
3889 /* packet delineator 1 clock */
3890 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 1);
3891 /* ADC 1 clock */
3892 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 1);
3893 /* FEC clock is shared between the two paths, only stop it
3894 when full standby is possible */
3895 if (full_standby)
3896 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3897 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3898 goto err;
3899 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3900 /* sampling 1 clock */
3901 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
3902 /* viterbi 1 clock */
3903 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 1);
3904 /* TS clock is shared between the two paths, only stop it
3905 when full standby is possible */
3906 if (full_standby)
3907 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3908 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3909 goto err;
3910 break;
3873 3911
3912 case STV090x_DEMODULATOR_1:
3913 /* power off ADC 2 */
3914 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
3915 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
3916 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
3917 goto err;
3918 /* power off DiSEqC 2 */
3919 reg = stv090x_read_reg(state, STV090x_TSTTNR4);
3920 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
3921 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
3922 goto err;
3923
3924 /* check whether path 1 is already sleeping, that is when
3925 ADC1 is off */
3926 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3927 if (STV090x_GETFIELD(reg, ADC1_PON_FIELD) == 0)
3928 full_standby = 1;
3929
3930 /* stop clocks */
3931 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
3932 /* packet delineator 2 clock */
3933 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 1);
3934 /* ADC 2 clock */
3935 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 1);
3936 /* FEC clock is shared between the two paths, only stop it
3937 when full standby is possible */
3938 if (full_standby)
3939 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3940 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3941 goto err;
3942 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3943 /* sampling 2 clock */
3944 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
3945 /* viterbi 2 clock */
3946 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 1);
3947 /* TS clock is shared between the two paths, only stop it
3948 when full standby is possible */
3949 if (full_standby)
3950 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3951 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3952 goto err;
3953 break;
3954
3955 default:
3956 dprintk(FE_ERROR, 1, "Wrong demodulator!");
3957 break;
3958 }
3959
3960 if (full_standby) {
3961 /* general power off */
3962 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3963 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
3964 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3965 goto err;
3966 }
3967
3968 mutex_unlock(&state->internal->demod_lock);
3874 return 0; 3969 return 0;
3875 3970
3876err_gateoff: 3971err_gateoff:
3877 stv090x_i2c_gate_ctrl(state, 0); 3972 stv090x_i2c_gate_ctrl(state, 0);
3878err: 3973err:
3974 mutex_unlock(&state->internal->demod_lock);
3879 dprintk(FE_ERROR, 1, "I/O error"); 3975 dprintk(FE_ERROR, 1, "I/O error");
3880 return -1; 3976 return -1;
3881} 3977}
@@ -3885,21 +3981,94 @@ static int stv090x_wakeup(struct dvb_frontend *fe)
3885 struct stv090x_state *state = fe->demodulator_priv; 3981 struct stv090x_state *state = fe->demodulator_priv;
3886 u32 reg; 3982 u32 reg;
3887 3983
3888 dprintk(FE_DEBUG, 1, "Wake %s from standby", 3984 dprintk(FE_DEBUG, 1, "Wake %s(%d) from standby",
3889 state->device == STV0900 ? "STV0900" : "STV0903"); 3985 state->device == STV0900 ? "STV0900" : "STV0903",
3986 state->demod);
3987
3988 mutex_lock(&state->internal->demod_lock);
3890 3989
3990 /* general power on */
3891 reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 3991 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3892 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00); 3992 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00);
3893 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) 3993 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3894 goto err; 3994 goto err;
3895 3995
3896 reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3996 switch (state->demod) {
3897 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1); 3997 case STV090x_DEMODULATOR_0:
3898 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 3998 /* power on ADC 1 */
3899 goto err; 3999 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
4000 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1);
4001 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
4002 goto err;
4003 /* power on DiSEqC 1 */
4004 reg = stv090x_read_reg(state, STV090x_TSTTNR2);
4005 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 1);
4006 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
4007 goto err;
4008
4009 /* activate clocks */
4010 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
4011 /* packet delineator 1 clock */
4012 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 0);
4013 /* ADC 1 clock */
4014 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 0);
4015 /* FEC clock */
4016 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
4017 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
4018 goto err;
4019 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
4020 /* sampling 1 clock */
4021 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 0);
4022 /* viterbi 1 clock */
4023 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 0);
4024 /* TS clock */
4025 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
4026 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
4027 goto err;
4028 break;
3900 4029
4030 case STV090x_DEMODULATOR_1:
4031 /* power on ADC 2 */
4032 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
4033 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 1);
4034 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
4035 goto err;
4036 /* power on DiSEqC 2 */
4037 reg = stv090x_read_reg(state, STV090x_TSTTNR4);
4038 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 1);
4039 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
4040 goto err;
4041
4042 /* activate clocks */
4043 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
4044 /* packet delineator 2 clock */
4045 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 0);
4046 /* ADC 2 clock */
4047 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 0);
4048 /* FEC clock */
4049 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
4050 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
4051 goto err;
4052 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
4053 /* sampling 2 clock */
4054 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 0);
4055 /* viterbi 2 clock */
4056 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 0);
4057 /* TS clock */
4058 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
4059 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
4060 goto err;
4061 break;
4062
4063 default:
4064 dprintk(FE_ERROR, 1, "Wrong demodulator!");
4065 break;
4066 }
4067
4068 mutex_unlock(&state->internal->demod_lock);
3901 return 0; 4069 return 0;
3902err: 4070err:
4071 mutex_unlock(&state->internal->demod_lock);
3903 dprintk(FE_ERROR, 1, "I/O error"); 4072 dprintk(FE_ERROR, 1, "I/O error");
3904 return -1; 4073 return -1;
3905} 4074}
@@ -4622,20 +4791,10 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4622 mutex_init(&state->internal->demod_lock); 4791 mutex_init(&state->internal->demod_lock);
4623 mutex_init(&state->internal->tuner_lock); 4792 mutex_init(&state->internal->tuner_lock);
4624 4793
4625 if (stv090x_sleep(&state->frontend) < 0) {
4626 dprintk(FE_ERROR, 1, "Error putting device to sleep");
4627 goto error;
4628 }
4629
4630 if (stv090x_setup(&state->frontend) < 0) { 4794 if (stv090x_setup(&state->frontend) < 0) {
4631 dprintk(FE_ERROR, 1, "Error setting up device"); 4795 dprintk(FE_ERROR, 1, "Error setting up device");
4632 goto error; 4796 goto error;
4633 } 4797 }
4634 if (stv090x_wakeup(&state->frontend) < 0) {
4635 dprintk(FE_ERROR, 1, "Error waking device");
4636 goto error;
4637 }
4638
4639 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", 4798 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
4640 state->device == STV0900 ? "STV0900" : "STV0903", 4799 state->device == STV0900 ? "STV0900" : "STV0903",
4641 demod, 4800 demod,