diff options
Diffstat (limited to 'drivers/media/dvb/frontends/tda10048.c')
| -rw-r--r-- | drivers/media/dvb/frontends/tda10048.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 4e2a7c8b2f6..93f6a75c238 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
| 28 | #include <linux/math64.h> | ||
| 28 | #include <asm/div64.h> | 29 | #include <asm/div64.h> |
| 29 | #include "dvb_frontend.h" | 30 | #include "dvb_frontend.h" |
| 30 | #include "dvb_math.h" | 31 | #include "dvb_math.h" |
| @@ -49,8 +50,8 @@ | |||
| 49 | #define TDA10048_CONF_C4_1 0x1E | 50 | #define TDA10048_CONF_C4_1 0x1E |
| 50 | #define TDA10048_CONF_C4_2 0x1F | 51 | #define TDA10048_CONF_C4_2 0x1F |
| 51 | #define TDA10048_CODE_IN_RAM 0x20 | 52 | #define TDA10048_CODE_IN_RAM 0x20 |
| 52 | #define TDA10048_CHANNEL_INFO_1_R 0x22 | 53 | #define TDA10048_CHANNEL_INFO1_R 0x22 |
| 53 | #define TDA10048_CHANNEL_INFO_2_R 0x23 | 54 | #define TDA10048_CHANNEL_INFO2_R 0x23 |
| 54 | #define TDA10048_CHANNEL_INFO1 0x24 | 55 | #define TDA10048_CHANNEL_INFO1 0x24 |
| 55 | #define TDA10048_CHANNEL_INFO2 0x25 | 56 | #define TDA10048_CHANNEL_INFO2 0x25 |
| 56 | #define TDA10048_TIME_ERROR_R 0x26 | 57 | #define TDA10048_TIME_ERROR_R 0x26 |
| @@ -63,8 +64,8 @@ | |||
| 63 | #define TDA10048_IT_STAT 0x32 | 64 | #define TDA10048_IT_STAT 0x32 |
| 64 | #define TDA10048_DSP_AD_LSB 0x3C | 65 | #define TDA10048_DSP_AD_LSB 0x3C |
| 65 | #define TDA10048_DSP_AD_MSB 0x3D | 66 | #define TDA10048_DSP_AD_MSB 0x3D |
| 66 | #define TDA10048_DSP_REF_LSB 0x3E | 67 | #define TDA10048_DSP_REG_LSB 0x3E |
| 67 | #define TDA10048_DSP_REF_MSB 0x3F | 68 | #define TDA10048_DSP_REG_MSB 0x3F |
| 68 | #define TDA10048_CONF_TRISTATE1 0x44 | 69 | #define TDA10048_CONF_TRISTATE1 0x44 |
| 69 | #define TDA10048_CONF_TRISTATE2 0x45 | 70 | #define TDA10048_CONF_TRISTATE2 0x45 |
| 70 | #define TDA10048_CONF_POLARITY 0x46 | 71 | #define TDA10048_CONF_POLARITY 0x46 |
| @@ -112,7 +113,7 @@ | |||
| 112 | #define TDA10048_FREE_REG_1 0xB2 | 113 | #define TDA10048_FREE_REG_1 0xB2 |
| 113 | #define TDA10048_FREE_REG_2 0xB3 | 114 | #define TDA10048_FREE_REG_2 0xB3 |
| 114 | #define TDA10048_CONF_C3_1 0xC0 | 115 | #define TDA10048_CONF_C3_1 0xC0 |
| 115 | #define TDA10048_CYBER_CTRL 0xC2 | 116 | #define TDA10048_CVBER_CTRL 0xC2 |
| 116 | #define TDA10048_CBER_NMAX_LSB 0xC4 | 117 | #define TDA10048_CBER_NMAX_LSB 0xC4 |
| 117 | #define TDA10048_CBER_NMAX_MSB 0xC5 | 118 | #define TDA10048_CBER_NMAX_MSB 0xC5 |
| 118 | #define TDA10048_CBER_LSB 0xC6 | 119 | #define TDA10048_CBER_LSB 0xC6 |
| @@ -120,7 +121,7 @@ | |||
| 120 | #define TDA10048_VBER_LSB 0xC8 | 121 | #define TDA10048_VBER_LSB 0xC8 |
| 121 | #define TDA10048_VBER_MID 0xC9 | 122 | #define TDA10048_VBER_MID 0xC9 |
| 122 | #define TDA10048_VBER_MSB 0xCA | 123 | #define TDA10048_VBER_MSB 0xCA |
| 123 | #define TDA10048_CYBER_LUT 0xCC | 124 | #define TDA10048_CVBER_LUT 0xCC |
| 124 | #define TDA10048_UNCOR_CTRL 0xCD | 125 | #define TDA10048_UNCOR_CTRL 0xCD |
| 125 | #define TDA10048_UNCOR_CPT_LSB 0xCE | 126 | #define TDA10048_UNCOR_CPT_LSB 0xCE |
| 126 | #define TDA10048_UNCOR_CPT_MSB 0xCF | 127 | #define TDA10048_UNCOR_CPT_MSB 0xCF |
| @@ -183,7 +184,7 @@ static struct init_tab { | |||
| 183 | { TDA10048_AGC_IF_MAX, 0xff }, | 184 | { TDA10048_AGC_IF_MAX, 0xff }, |
| 184 | { TDA10048_AGC_THRESHOLD_MSB, 0x00 }, | 185 | { TDA10048_AGC_THRESHOLD_MSB, 0x00 }, |
| 185 | { TDA10048_AGC_THRESHOLD_LSB, 0x70 }, | 186 | { TDA10048_AGC_THRESHOLD_LSB, 0x70 }, |
| 186 | { TDA10048_CYBER_CTRL, 0x38 }, | 187 | { TDA10048_CVBER_CTRL, 0x38 }, |
| 187 | { TDA10048_AGC_GAINS, 0x12 }, | 188 | { TDA10048_AGC_GAINS, 0x12 }, |
| 188 | { TDA10048_CONF_XO, 0x00 }, | 189 | { TDA10048_CONF_XO, 0x00 }, |
| 189 | { TDA10048_CONF_TS1, 0x07 }, | 190 | { TDA10048_CONF_TS1, 0x07 }, |
| @@ -688,7 +689,7 @@ static int tda10048_get_tps(struct tda10048_state *state, | |||
| 688 | p->guard_interval = GUARD_INTERVAL_1_4; | 689 | p->guard_interval = GUARD_INTERVAL_1_4; |
| 689 | break; | 690 | break; |
| 690 | } | 691 | } |
| 691 | switch (val & 0x02) { | 692 | switch (val & 0x03) { |
| 692 | case 0: | 693 | case 0: |
| 693 | p->transmission_mode = TRANSMISSION_MODE_2K; | 694 | p->transmission_mode = TRANSMISSION_MODE_2K; |
| 694 | break; | 695 | break; |
| @@ -765,6 +766,8 @@ static int tda10048_set_frontend(struct dvb_frontend *fe, | |||
| 765 | 766 | ||
| 766 | /* Enable demod TPS auto detection and begin acquisition */ | 767 | /* Enable demod TPS auto detection and begin acquisition */ |
| 767 | tda10048_writereg(state, TDA10048_AUTO, 0x57); | 768 | tda10048_writereg(state, TDA10048_AUTO, 0x57); |
| 769 | /* trigger cber and vber acquisition */ | ||
| 770 | tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x3B); | ||
| 768 | 771 | ||
| 769 | return 0; | 772 | return 0; |
| 770 | } | 773 | } |
| @@ -830,12 +833,27 @@ static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
| 830 | static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber) | 833 | static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber) |
| 831 | { | 834 | { |
| 832 | struct tda10048_state *state = fe->demodulator_priv; | 835 | struct tda10048_state *state = fe->demodulator_priv; |
| 836 | static u32 cber_current; | ||
| 837 | u32 cber_nmax; | ||
| 838 | u64 cber_tmp; | ||
| 833 | 839 | ||
| 834 | dprintk(1, "%s()\n", __func__); | 840 | dprintk(1, "%s()\n", __func__); |
| 835 | 841 | ||
| 836 | /* TODO: A reset may be required here */ | 842 | /* update cber on interrupt */ |
| 837 | *ber = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 | | 843 | if (tda10048_readreg(state, TDA10048_SOFT_IT_C3) & 0x01) { |
| 838 | tda10048_readreg(state, TDA10048_CBER_LSB); | 844 | cber_tmp = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 | |
| 845 | tda10048_readreg(state, TDA10048_CBER_LSB); | ||
| 846 | cber_nmax = tda10048_readreg(state, TDA10048_CBER_NMAX_MSB) << 8 | | ||
| 847 | tda10048_readreg(state, TDA10048_CBER_NMAX_LSB); | ||
| 848 | cber_tmp *= 100000000; | ||
| 849 | cber_tmp *= 2; | ||
| 850 | cber_tmp = div_u64(cber_tmp, (cber_nmax * 32) + 1); | ||
| 851 | cber_current = (u32)cber_tmp; | ||
| 852 | /* retrigger cber acquisition */ | ||
| 853 | tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x39); | ||
| 854 | } | ||
| 855 | /* actual cber is (*ber)/1e8 */ | ||
| 856 | *ber = cber_current; | ||
| 839 | 857 | ||
| 840 | return 0; | 858 | return 0; |
| 841 | } | 859 | } |
| @@ -1015,6 +1033,9 @@ static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | |||
| 1015 | 1033 | ||
| 1016 | *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 | | 1034 | *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 | |
| 1017 | tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB); | 1035 | tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB); |
| 1036 | /* clear the uncorrected TS packets counter when saturated */ | ||
| 1037 | if (*ucblocks == 0xFFFF) | ||
| 1038 | tda10048_writereg(state, TDA10048_UNCOR_CTRL, 0x80); | ||
| 1018 | 1039 | ||
| 1019 | return 0; | 1040 | return 0; |
| 1020 | } | 1041 | } |
