Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Andreas Regel and committed by
Mauro Carvalho Chehab
5bd0dc2d 2c2c441b

+185 -26
+185 -26
drivers/media/dvb/frontends/stv090x.c
··· 3846 3846 { 3847 3847 struct stv090x_state *state = fe->demodulator_priv; 3848 3848 u32 reg; 3849 + u8 full_standby = 0; 3849 3850 3850 3851 if (stv090x_i2c_gate_ctrl(state, 1) < 0) 3851 3852 goto err; ··· 3859 3858 if (stv090x_i2c_gate_ctrl(state, 0) < 0) 3860 3859 goto err; 3861 3860 3862 - dprintk(FE_DEBUG, 1, "Set %s to sleep", 3863 - state->device == STV0900 ? "STV0900" : "STV0903"); 3861 + dprintk(FE_DEBUG, 1, "Set %s(%d) to sleep", 3862 + state->device == STV0900 ? "STV0900" : "STV0903", 3863 + state->demod); 3864 3864 3865 - reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 3866 - STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01); 3867 - if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) 3868 - goto err; 3865 + mutex_lock(&state->internal->demod_lock); 3869 3866 3870 - reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3871 - STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); 3872 - if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 3873 - goto err; 3867 + switch (state->demod) { 3868 + case STV090x_DEMODULATOR_0: 3869 + /* power off ADC 1 */ 3870 + reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3871 + STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); 3872 + if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 3873 + goto err; 3874 + /* power off DiSEqC 1 */ 3875 + reg = stv090x_read_reg(state, STV090x_TSTTNR2); 3876 + STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0); 3877 + if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0) 3878 + goto err; 3874 3879 3880 + /* check whether path 2 is already sleeping, that is when 3881 + ADC2 is off */ 3882 + reg = stv090x_read_reg(state, STV090x_TSTTNR3); 3883 + if (STV090x_GETFIELD(reg, ADC2_PON_FIELD) == 0) 3884 + full_standby = 1; 3885 + 3886 + /* stop clocks */ 3887 + reg = stv090x_read_reg(state, STV090x_STOPCLK1); 3888 + /* packet delineator 1 clock */ 3889 + STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 1); 3890 + /* ADC 1 clock */ 3891 + STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 1); 3892 + /* FEC clock is shared between the two paths, only stop it 3893 + when full standby is possible */ 3894 + if (full_standby) 3895 + STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); 3896 + if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 3897 + goto err; 3898 + reg = stv090x_read_reg(state, STV090x_STOPCLK2); 3899 + /* sampling 1 clock */ 3900 + STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1); 3901 + /* viterbi 1 clock */ 3902 + STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 1); 3903 + /* TS clock is shared between the two paths, only stop it 3904 + when full standby is possible */ 3905 + if (full_standby) 3906 + STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); 3907 + if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 3908 + goto err; 3909 + break; 3910 + 3911 + case STV090x_DEMODULATOR_1: 3912 + /* power off ADC 2 */ 3913 + reg = stv090x_read_reg(state, STV090x_TSTTNR3); 3914 + STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0); 3915 + if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) 3916 + goto err; 3917 + /* power off DiSEqC 2 */ 3918 + reg = stv090x_read_reg(state, STV090x_TSTTNR4); 3919 + STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0); 3920 + if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0) 3921 + goto err; 3922 + 3923 + /* check whether path 1 is already sleeping, that is when 3924 + ADC1 is off */ 3925 + reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3926 + if (STV090x_GETFIELD(reg, ADC1_PON_FIELD) == 0) 3927 + full_standby = 1; 3928 + 3929 + /* stop clocks */ 3930 + reg = stv090x_read_reg(state, STV090x_STOPCLK1); 3931 + /* packet delineator 2 clock */ 3932 + STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 1); 3933 + /* ADC 2 clock */ 3934 + STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 1); 3935 + /* FEC clock is shared between the two paths, only stop it 3936 + when full standby is possible */ 3937 + if (full_standby) 3938 + STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); 3939 + if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 3940 + goto err; 3941 + reg = stv090x_read_reg(state, STV090x_STOPCLK2); 3942 + /* sampling 2 clock */ 3943 + STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1); 3944 + /* viterbi 2 clock */ 3945 + STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 1); 3946 + /* TS clock is shared between the two paths, only stop it 3947 + when full standby is possible */ 3948 + if (full_standby) 3949 + STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); 3950 + if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 3951 + goto err; 3952 + break; 3953 + 3954 + default: 3955 + dprintk(FE_ERROR, 1, "Wrong demodulator!"); 3956 + break; 3957 + } 3958 + 3959 + if (full_standby) { 3960 + /* general power off */ 3961 + reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 3962 + STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01); 3963 + if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) 3964 + goto err; 3965 + } 3966 + 3967 + mutex_unlock(&state->internal->demod_lock); 3875 3968 return 0; 3876 3969 3877 3970 err_gateoff: 3878 3971 stv090x_i2c_gate_ctrl(state, 0); 3879 3972 err: 3973 + mutex_unlock(&state->internal->demod_lock); 3880 3974 dprintk(FE_ERROR, 1, "I/O error"); 3881 3975 return -1; 3882 3976 } ··· 3981 3885 struct stv090x_state *state = fe->demodulator_priv; 3982 3886 u32 reg; 3983 3887 3984 - dprintk(FE_DEBUG, 1, "Wake %s from standby", 3985 - state->device == STV0900 ? "STV0900" : "STV0903"); 3888 + dprintk(FE_DEBUG, 1, "Wake %s(%d) from standby", 3889 + state->device == STV0900 ? "STV0900" : "STV0903", 3890 + state->demod); 3986 3891 3892 + mutex_lock(&state->internal->demod_lock); 3893 + 3894 + /* general power on */ 3987 3895 reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 3988 3896 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00); 3989 3897 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) 3990 3898 goto err; 3991 3899 3992 - reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3993 - STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1); 3994 - if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 3995 - goto err; 3900 + switch (state->demod) { 3901 + case STV090x_DEMODULATOR_0: 3902 + /* power on ADC 1 */ 3903 + reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3904 + STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1); 3905 + if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 3906 + goto err; 3907 + /* power on DiSEqC 1 */ 3908 + reg = stv090x_read_reg(state, STV090x_TSTTNR2); 3909 + STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 1); 3910 + if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0) 3911 + goto err; 3996 3912 3913 + /* activate clocks */ 3914 + reg = stv090x_read_reg(state, STV090x_STOPCLK1); 3915 + /* packet delineator 1 clock */ 3916 + STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 0); 3917 + /* ADC 1 clock */ 3918 + STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 0); 3919 + /* FEC clock */ 3920 + STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0); 3921 + if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 3922 + goto err; 3923 + reg = stv090x_read_reg(state, STV090x_STOPCLK2); 3924 + /* sampling 1 clock */ 3925 + STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 0); 3926 + /* viterbi 1 clock */ 3927 + STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 0); 3928 + /* TS clock */ 3929 + STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0); 3930 + if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 3931 + goto err; 3932 + break; 3933 + 3934 + case STV090x_DEMODULATOR_1: 3935 + /* power on ADC 2 */ 3936 + reg = stv090x_read_reg(state, STV090x_TSTTNR3); 3937 + STV090x_SETFIELD(reg, ADC2_PON_FIELD, 1); 3938 + if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) 3939 + goto err; 3940 + /* power on DiSEqC 2 */ 3941 + reg = stv090x_read_reg(state, STV090x_TSTTNR4); 3942 + STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 1); 3943 + if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0) 3944 + goto err; 3945 + 3946 + /* activate clocks */ 3947 + reg = stv090x_read_reg(state, STV090x_STOPCLK1); 3948 + /* packet delineator 2 clock */ 3949 + STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 0); 3950 + /* ADC 2 clock */ 3951 + STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 0); 3952 + /* FEC clock */ 3953 + STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0); 3954 + if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 3955 + goto err; 3956 + reg = stv090x_read_reg(state, STV090x_STOPCLK2); 3957 + /* sampling 2 clock */ 3958 + STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 0); 3959 + /* viterbi 2 clock */ 3960 + STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 0); 3961 + /* TS clock */ 3962 + STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0); 3963 + if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 3964 + goto err; 3965 + break; 3966 + 3967 + default: 3968 + dprintk(FE_ERROR, 1, "Wrong demodulator!"); 3969 + break; 3970 + } 3971 + 3972 + mutex_unlock(&state->internal->demod_lock); 3997 3973 return 0; 3998 3974 err: 3975 + mutex_unlock(&state->internal->demod_lock); 3999 3976 dprintk(FE_ERROR, 1, "I/O error"); 4000 3977 return -1; 4001 3978 } ··· 4791 4622 mutex_init(&state->internal->demod_lock); 4792 4623 mutex_init(&state->internal->tuner_lock); 4793 4624 4794 - if (stv090x_sleep(&state->frontend) < 0) { 4795 - dprintk(FE_ERROR, 1, "Error putting device to sleep"); 4796 - goto error; 4797 - } 4798 - 4799 4625 if (stv090x_setup(&state->frontend) < 0) { 4800 4626 dprintk(FE_ERROR, 1, "Error setting up device"); 4801 4627 goto error; 4802 4628 } 4803 - if (stv090x_wakeup(&state->frontend) < 0) { 4804 - dprintk(FE_ERROR, 1, "Error waking device"); 4805 - goto error; 4806 - } 4807 - 4808 4629 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", 4809 4630 state->device == STV0900 ? "STV0900" : "STV0903", 4810 4631 demod,