aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/tda10048.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/tda10048.c')
-rw-r--r--drivers/media/dvb/frontends/tda10048.c43
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)
830static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber) 833static 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}