mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2025-03-01 10:35:23 +00:00
Merge branch 'internal'
This commit is contained in:
@@ -35,8 +35,11 @@
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_math.h"
|
||||
#include "cxd2843.h"
|
||||
|
||||
#define Log10x100(x) ((s32)(((((u64) intlog2(x) * 0x1e1a5e2e) >> 47 ) + 1) >> 1))
|
||||
|
||||
#define USE_ALGO 1
|
||||
|
||||
enum demod_type { CXD2843, CXD2837, CXD2838 };
|
||||
@@ -329,7 +332,7 @@ static inline u32 MulDiv32(u32 a, u32 b, u32 c)
|
||||
static int read_tps(struct cxd_state *state, u8 *tps)
|
||||
{
|
||||
if (state->last_status != 0x1f)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
freeze_regst(state);
|
||||
readregst_unlocked(state, 0x10, 0x2f, tps, 7);
|
||||
@@ -337,6 +340,63 @@ static int read_tps(struct cxd_state *state, u8 *tps)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read DVBT2 OFDM Info */
|
||||
/* OFDMInfo[0] [5] OFDM_MIXED */
|
||||
/* OFDMInfo[0] [4] OFDM_MISO */
|
||||
/* OFDMInfo[0] [2:0] OFDM_FFTSIZE[2:0] */
|
||||
/* OFDMInfo[1] [6:4] OFDM_GI[2:0] */
|
||||
/* OFDMInfo[1] [2:0] OFDM_PP[2:0] */
|
||||
/* OFDMInfo[2] [4] OFDM_BWT_EXT */
|
||||
/* OFDMInfo[2] [3:0] OFDM_PAPR[3:0] */
|
||||
/* OFDMInfo[3] [3:0] OFDM_NDSYM[11:8] */
|
||||
/* OFDMInfo[4] [7:0] OFDM_NDSYM[7:0] */
|
||||
|
||||
static int read_t2_ofdm_info(struct cxd_state *state, u8 *ofdm)
|
||||
{
|
||||
if (state->last_status != 0x1f)
|
||||
return -1;
|
||||
|
||||
freeze_regst(state);
|
||||
readregst_unlocked(state, 0x20, 0x5c, ofdm, 5);
|
||||
unfreeze_regst(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read DVBT2 QAM,
|
||||
Data PLP
|
||||
0 [7:0] L1POST_PLP_ID[7:0]
|
||||
1 [2:0] L1POST_PLP_TYPE[2:0]
|
||||
2 [4:0] L1POST_PLP_PAYLOAD_TYPE[4:0]
|
||||
3 [0] L1POST_FF_FLAG
|
||||
4 [2:0] L1POST_FIRST_RF_IDX[2:0]
|
||||
5 [7:0] L1POST_FIRST_FRAME_IDX[7:0]
|
||||
6 [7:0] L1POST_PLP_GROUP_ID[7:0]
|
||||
7 [2:0] L1POST_PLP_COD[2:0]
|
||||
8 [2:0] L1POST_PLP_MOD[2:0]
|
||||
9 [0] L1POST_PLP_ROTATION
|
||||
10 [1:0] L1POST_PLP_FEC_TYPE[1:0]
|
||||
11 [1:0] L1POST_PLP_NUM_BLOCKS_MAX[9:8]
|
||||
12 [7:0] L1POST_PLP_NUM_BLOCKS_MAX[7:0]
|
||||
13 [7:0] L1POST_FRAME_INTERVAL[7:0]
|
||||
14 [7:0] L1POST_TIME_IL_LENGTH[7:0]
|
||||
15 [0] L1POST_TIME_IL_TYPE
|
||||
16 [0] L1POST_IN_BAND_FLAG
|
||||
17 [7:0] L1POST_RESERVED_1[15:8]
|
||||
18 [7:0] L1POST_RESERVED_1[7:0]
|
||||
19-37 same for common PLP
|
||||
*/
|
||||
|
||||
static int read_t2_tlp_info(struct cxd_state *state, u8 off, u8 count, u8 *tlp)
|
||||
{
|
||||
if (state->last_status != 0x1f)
|
||||
return -1;
|
||||
|
||||
freeze_regst(state);
|
||||
readregst_unlocked(state, 0x22, 0x54 + off, tlp, count);
|
||||
unfreeze_regst(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Active_to_Sleep(struct cxd_state *state)
|
||||
{
|
||||
if (state->state <= Sleep)
|
||||
@@ -1174,7 +1234,7 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
state->bandwidth = fe->dtv_property_cache.bandwidth_hz;
|
||||
state->bw = (fe->dtv_property_cache.bandwidth_hz + 999999) / 1000000;
|
||||
if (fe->dtv_property_cache.stream_id == 0xffffffff) {
|
||||
if (fe->dtv_property_cache.stream_id == NO_STREAM_ID_FILTER) {
|
||||
state->DataSliceID = 0xffffffff;
|
||||
state->plp = 0xffffffff;
|
||||
} else {
|
||||
@@ -1273,18 +1333,20 @@ static int read_snr(struct dvb_frontend *fe, u16 *snr);
|
||||
|
||||
static int get_stats(struct dvb_frontend *fe)
|
||||
{
|
||||
struct cxd_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u16 val;
|
||||
s64 str;
|
||||
|
||||
if (fe->ops.tuner_ops.get_rf_strength)
|
||||
fe->ops.tuner_ops.get_rf_strength(fe, &val);
|
||||
else
|
||||
val = 0;
|
||||
|
||||
str = 1000 * (s64) (s16) val;
|
||||
str -= 108750;
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].uvalue = 1000 * (s64) (s16) val;
|
||||
p->strength.stat[0].uvalue = str;
|
||||
|
||||
read_snr(fe, &val);
|
||||
p->cnr.len = 1;
|
||||
@@ -1313,6 +1375,12 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
if (rdata & 0x20)
|
||||
*status |= 0x1f;
|
||||
}
|
||||
if (*status == 0x1f && state->FirstTimeLock) {
|
||||
readregst(state, 0x40, 0x19, &rdata, 1);
|
||||
rdata &= 0x07;
|
||||
state->BERScaleMax = ( rdata < 2 ) ? 18 : 19;
|
||||
state->FirstTimeLock = 0;
|
||||
}
|
||||
break;
|
||||
case ActiveT:
|
||||
readregst(state, 0x10, 0x10, &rdata, 1);
|
||||
@@ -1323,6 +1391,16 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
if (rdata & 0x20)
|
||||
*status |= 0x1f;
|
||||
}
|
||||
if (*status == 0x1f && state->FirstTimeLock) {
|
||||
u8 tps[7];
|
||||
|
||||
read_tps(state, tps);
|
||||
state->BERScaleMax =
|
||||
(((tps[0] >> 6) & 0x03) < 2 ) ? 17 : 18;
|
||||
if ((tps[0] & 7) < 2)
|
||||
state->BERScaleMax--;
|
||||
state->FirstTimeLock = 0;
|
||||
}
|
||||
break;
|
||||
case ActiveT2:
|
||||
readregst(state, 0x20, 0x10, &rdata, 1);
|
||||
@@ -1369,6 +1447,12 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
if (rdata & 0x01)
|
||||
*status |= 0x18;
|
||||
}
|
||||
if (*status == 0x1f && state->FirstTimeLock) {
|
||||
/* readregst(state, 0x40, 0x19, &rdata, 1); */
|
||||
/* rdata &= 0x07; */
|
||||
/* state->BERScaleMax = ( rdata < 2 ) ? 18 : 19; */
|
||||
state->FirstTimeLock = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1407,8 +1491,44 @@ static int get_ber_t(struct cxd_state *state, u32 *n, u32 *d)
|
||||
|
||||
static int get_ber_t2(struct cxd_state *state, u32 *n, u32 *d)
|
||||
{
|
||||
u8 BERRegs[4];
|
||||
u8 Scale;
|
||||
u8 FECType;
|
||||
u8 CodeRate;
|
||||
static const u32 nBCHBitsLookup[2][8] = {
|
||||
/* R1_2 R3_5 R2_3 R3_4 R4_5 R5_6 R1_3 R2_5 */
|
||||
{7200, 9720, 10800, 11880, 12600, 13320, 5400, 6480}, /* 16K FEC */
|
||||
{32400, 38880, 43200, 48600, 51840, 54000, 21600, 25920} /* 64k FEC */
|
||||
};
|
||||
|
||||
*n = 0;
|
||||
*d = 1;
|
||||
freeze_regst(state);
|
||||
readregst(state, 0x24, 0x40, BERRegs, 4);
|
||||
readregst(state, 0x22, 0x5e, &FECType, 1);
|
||||
readregst(state, 0x22, 0x5b, &CodeRate, 1);
|
||||
|
||||
FECType &= 0x03;
|
||||
CodeRate &= 0x07;
|
||||
unfreeze_regst(state);
|
||||
if (FECType > 1)
|
||||
return 0;
|
||||
|
||||
|
||||
readregst(state, 0x20, 0x72, &Scale, 1);
|
||||
Scale &= 0x0F;
|
||||
if (BERRegs[0] & 0x01) {
|
||||
state->LastBERNominator = (((u32) BERRegs[1] & 0x3F) << 16) |
|
||||
(((u32) BERRegs[2]) << 8) | BERRegs[3];
|
||||
state->LastBERDenominator = nBCHBitsLookup[FECType][CodeRate] << Scale;
|
||||
if (state->LastBERNominator < 256 &&
|
||||
Scale < state->BERScaleMax) {
|
||||
writebitst(state, 0x20, 0x72, Scale + 1, 0x0F);
|
||||
} else if (state->LastBERNominator > 512 && Scale > 8)
|
||||
writebitst(state, 0x20, 0x72, Scale - 1, 0x0F);
|
||||
}
|
||||
*n = state->LastBERNominator;
|
||||
*d = state->LastBERDenominator;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1458,7 +1578,7 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct cxd_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 n, d;
|
||||
u32 n = 0, d = 1;
|
||||
int s = 0;
|
||||
|
||||
*ber = 0;
|
||||
@@ -1504,57 +1624,63 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 Log10x100(u32 x)
|
||||
{
|
||||
static u32 LookupTable[100] = {
|
||||
101157945, 103514217, 105925373, 108392691, 110917482,
|
||||
113501082, 116144861, 118850223, 121618600, 124451461,
|
||||
127350308, 130316678, 133352143, 136458314, 139636836,
|
||||
142889396, 146217717, 149623566, 153108746, 156675107,
|
||||
160324539, 164058977, 167880402, 171790839, 175792361,
|
||||
179887092, 184077200, 188364909, 192752491, 197242274,
|
||||
201836636, 206538016, 211348904, 216271852, 221309471,
|
||||
226464431, 231739465, 237137371, 242661010, 248313311,
|
||||
254097271, 260015956, 266072506, 272270131, 278612117,
|
||||
285101827, 291742701, 298538262, 305492111, 312607937,
|
||||
319889511, 327340695, 334965439, 342767787, 350751874,
|
||||
358921935, 367282300, 375837404, 384591782, 393550075,
|
||||
402717034, 412097519, 421696503, 431519077, 441570447,
|
||||
451855944, 462381021, 473151259, 484172368, 495450191,
|
||||
506990708, 518800039, 530884444, 543250331, 555904257,
|
||||
568852931, 582103218, 595662144, 609536897, 623734835,
|
||||
638263486, 653130553, 668343918, 683911647, 699841996,
|
||||
716143410, 732824533, 749894209, 767361489, 785235635,
|
||||
803526122, 822242650, 841395142, 860993752, 881048873,
|
||||
901571138, 922571427, 944060876, 966050879, 988553095,
|
||||
};
|
||||
s32 y;
|
||||
int i;
|
||||
|
||||
if (x == 0)
|
||||
return 0;
|
||||
y = 800;
|
||||
if (x >= 1000000000) {
|
||||
x /= 10;
|
||||
y += 100;
|
||||
}
|
||||
|
||||
while (x < 100000000) {
|
||||
x *= 10;
|
||||
y -= 100;
|
||||
}
|
||||
i = 0;
|
||||
while (i < 100 && x > LookupTable[i])
|
||||
i += 1;
|
||||
y += i;
|
||||
return y;
|
||||
}
|
||||
|
||||
#if 0
|
||||
+NTSTATUS CCXD2843ER::GetT2PLPIds(DD_T2_PLPIDS* pT2_PLPIDS)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
- *pReturned = 0;
|
||||
+
|
||||
if( m_DemodState != ActiveT2 ) return STATUS_NOT_IMPLEMENTED;
|
||||
- if( m_LastLockStatus < TSLock || m_LastLockStatus == Unlock ) return status;
|
||||
+ if( m_LastLockStatus < TSLock ) return status;
|
||||
|
||||
do
|
||||
{
|
||||
+ BYTE tmp;
|
||||
+
|
||||
CHK_ERROR(FreezeRegsT());
|
||||
|
||||
+ CHK_ERROR(ReadRegT(0x20,0x5C,&tmp)); // OFDM Info
|
||||
+
|
||||
+ if( tmp & 0x20 ) pT2_PLPIDS->Flags |= DD_T2_PLPIDS_FEF;
|
||||
+ if( m_T2Profile == T2P_Lite ) pT2_PLPIDS->Flags |= DD_T2_PLPIDS_LITE;
|
||||
+
|
||||
+ CHK_ERROR(ReadRegT(0x22,0x54,&tmp));
|
||||
+ pT2_PLPIDS->PLPID = tmp;
|
||||
+
|
||||
+ CHK_ERROR(ReadRegT(0x22,0x54 + 19 + 13,&tmp)); // Interval
|
||||
+ if( tmp > 0 )
|
||||
+ {
|
||||
+ CHK_ERROR(ReadRegT(0x22,0x54 + 19,&tmp));
|
||||
+ pT2_PLPIDS->CommonPLPID = tmp;
|
||||
+ }
|
||||
+
|
||||
BYTE nPids = 0;
|
||||
CHK_ERROR(ReadRegT(0x22,0x7F,&nPids));
|
||||
|
||||
- pValues[0] = nPids;
|
||||
- if( nPids >= nValues ) nPids = BYTE(nValues-1);
|
||||
+ pT2_PLPIDS->NumPLPS = nPids;
|
||||
+ CHK_ERROR(ReadRegT(0x22,0x80,&pT2_PLPIDS->PLPList[0], nPids > 128 ? 128 : nPids));
|
||||
|
||||
- CHK_ERROR(ReadRegT(0x22,0x80,&pValues[1], nPids > 128 ? 128 : nPids));
|
||||
-
|
||||
if( nPids > 128 )
|
||||
{
|
||||
- CHK_ERROR(ReadRegT(0x23,0x10,&pValues[129], nPids - 128));
|
||||
+ CHK_ERROR(ReadRegT(0x23,0x10,&pT2_PLPIDS->PLPList[128], nPids - 128));
|
||||
}
|
||||
|
||||
- *pReturned = nPids + 1;
|
||||
+
|
||||
}
|
||||
while(0);
|
||||
UnFreezeRegsT();
|
||||
|
||||
static void GetPLPIds(struct cxd_state *state, u32 nValues,
|
||||
u8 *Values, u32 *Returned)
|
||||
{
|
||||
u8 nPids = 0;
|
||||
u8 nPids = 0, tmp;
|
||||
|
||||
*Returned = 0;
|
||||
if (state->state != ActiveT2)
|
||||
@@ -1780,6 +1906,110 @@ static int get_algo(struct dvb_frontend *fe)
|
||||
return DVBFE_ALGO_HW;
|
||||
}
|
||||
|
||||
static int get_fe_t2(struct cxd_state *state)
|
||||
{
|
||||
struct dvb_frontend *fe = &state->frontend;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u8 ofdm[5], modcod[2];
|
||||
|
||||
freeze_regst(state);
|
||||
readregst_unlocked(state, 0x20, 0x5c, ofdm, 5);
|
||||
readregst_unlocked(state, 0x22, 0x5b, modcod, 2);
|
||||
unfreeze_regst(state);
|
||||
|
||||
switch (modcod[0] & 0x07) {
|
||||
case 0:
|
||||
p->fec_inner = FEC_1_2;
|
||||
break;
|
||||
case 1:
|
||||
p->fec_inner = FEC_3_5;
|
||||
break;
|
||||
case 2:
|
||||
p->fec_inner = FEC_2_3;
|
||||
break;
|
||||
case 3:
|
||||
p->fec_inner = FEC_3_4;
|
||||
break;
|
||||
case 4:
|
||||
p->fec_inner = FEC_4_5;
|
||||
break;
|
||||
case 5:
|
||||
p->fec_inner = FEC_5_6;
|
||||
break;
|
||||
case 6:
|
||||
p->fec_inner = FEC_1_3;
|
||||
break;
|
||||
case 7:
|
||||
p->fec_inner = FEC_2_5;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (modcod[1] & 0x07) {
|
||||
case 0:
|
||||
p->modulation = QPSK;
|
||||
break;
|
||||
case 1:
|
||||
p->modulation = QAM_16;
|
||||
break;
|
||||
case 2:
|
||||
p->modulation = QAM_64;
|
||||
break;
|
||||
case 3:
|
||||
p->modulation = QAM_256;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ofdm[0] & 0x07) {
|
||||
case 0:
|
||||
p->transmission_mode = TRANSMISSION_MODE_2K;
|
||||
break;
|
||||
case 1:
|
||||
p->transmission_mode = TRANSMISSION_MODE_8K;
|
||||
break;
|
||||
case 2:
|
||||
p->transmission_mode = TRANSMISSION_MODE_4K;
|
||||
break;
|
||||
case 3:
|
||||
p->transmission_mode = TRANSMISSION_MODE_1K;
|
||||
break;
|
||||
case 4:
|
||||
p->transmission_mode = TRANSMISSION_MODE_16K;
|
||||
break;
|
||||
case 5:
|
||||
p->transmission_mode = TRANSMISSION_MODE_32K;
|
||||
break;
|
||||
case 6:
|
||||
p->transmission_mode = TRANSMISSION_MODE_64K;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((ofdm[1] >> 4) & 0x07) {
|
||||
case 0:
|
||||
p->guard_interval = GUARD_INTERVAL_1_32;
|
||||
break;
|
||||
case 1:
|
||||
p->guard_interval = GUARD_INTERVAL_1_16;
|
||||
break;
|
||||
case 2:
|
||||
p->guard_interval = GUARD_INTERVAL_1_8;
|
||||
break;
|
||||
case 3:
|
||||
p->guard_interval = GUARD_INTERVAL_1_4;
|
||||
break;
|
||||
case 4:
|
||||
p->guard_interval = GUARD_INTERVAL_1_128;
|
||||
break;
|
||||
case 5:
|
||||
p->guard_interval = GUARD_INTERVAL_19_128;
|
||||
break;
|
||||
case 6:
|
||||
p->guard_interval = GUARD_INTERVAL_19_256;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_fe_t(struct cxd_state *state)
|
||||
{
|
||||
struct dvb_frontend *fe = &state->frontend;
|
||||
@@ -1907,6 +2137,7 @@ static int get_frontend(struct dvb_frontend *fe)
|
||||
get_fe_t(state);
|
||||
break;
|
||||
case ActiveT2:
|
||||
get_fe_t2(state);
|
||||
break;
|
||||
case ActiveC:
|
||||
get_fe_c(state);
|
||||
|
@@ -4866,10 +4866,6 @@ static int drxk_set_parameters (struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *p)
|
||||
#endif
|
||||
{
|
||||
#ifndef USE_API3
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 delsys = p->delivery_system, old_delsys;
|
||||
#endif
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
u32 IF;
|
||||
|
||||
@@ -4896,7 +4892,7 @@ static int drxk_set_parameters (struct dvb_frontend *fe,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drxk_c_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
|
||||
static int drxk_c_get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
//struct drxk_state *state = fe->demodulator_priv;
|
||||
//printk("%s\n", __FUNCTION__);
|
||||
@@ -4990,7 +4986,7 @@ static int drxk_t_sleep(struct dvb_frontend* fe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drxk_t_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
|
||||
static int drxk_t_get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
//struct drxk_state *state = fe->demodulator_priv;
|
||||
//printk("%s\n", __FUNCTION__);
|
||||
|
@@ -193,7 +193,8 @@ static int read_register_unlocked(struct mxl *state, u32 reg, u32 *val)
|
||||
if (stat)
|
||||
pr_err("i2c read error 1\n");
|
||||
if (!stat)
|
||||
stat = i2cread(state, (u8 *) val, MXL_HYDRA_REG_SIZE_IN_BYTES);
|
||||
stat = i2cread(state, (u8 *) val,
|
||||
MXL_HYDRA_REG_SIZE_IN_BYTES);
|
||||
le32_to_cpus(val);
|
||||
if (stat)
|
||||
pr_err("i2c read error 2\n");
|
||||
@@ -218,7 +219,8 @@ static int send_command(struct mxl *state, u32 size, u8 *buf)
|
||||
mutex_unlock(&state->base->i2c_lock);
|
||||
usleep_range(1000, 2000);
|
||||
mutex_lock(&state->base->i2c_lock);
|
||||
read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR, &val);
|
||||
read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR,
|
||||
&val);
|
||||
}
|
||||
if (!count) {
|
||||
pr_info("mxl5xx: send_command busy\n");
|
||||
@@ -247,7 +249,8 @@ static int write_register(struct mxl *state, u32 reg, u32 val)
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int write_register_block(struct mxl *state, u32 reg, u32 size, u8 *data)
|
||||
static int write_register_block(struct mxl *state, u32 reg,
|
||||
u32 size, u8 *data)
|
||||
{
|
||||
int stat;
|
||||
u8 *buf = state->base->buf;
|
||||
@@ -308,7 +311,8 @@ static int read_register(struct mxl *state, u32 reg, u32 *val)
|
||||
if (stat)
|
||||
pr_err("i2c read error 1\n");
|
||||
if (!stat)
|
||||
stat = i2cread(state, (u8 *) val, MXL_HYDRA_REG_SIZE_IN_BYTES);
|
||||
stat = i2cread(state, (u8 *) val,
|
||||
MXL_HYDRA_REG_SIZE_IN_BYTES);
|
||||
mutex_unlock(&state->base->i2c_lock);
|
||||
le32_to_cpus(val);
|
||||
if (stat)
|
||||
@@ -443,8 +447,10 @@ static int CfgDemodAbortTune(struct mxl *state)
|
||||
u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN];
|
||||
|
||||
abortTuneCmd.demodId = state->demod;
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE, cmdSize, &abortTuneCmd, cmdBuff);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE,
|
||||
cmdSize, &abortTuneCmd, cmdBuff);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
}
|
||||
|
||||
static int reset_fec_counter(struct mxl *state)
|
||||
@@ -456,7 +462,8 @@ static int reset_fec_counter(struct mxl *state)
|
||||
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_RESET_FEC_COUNTER_CMD,
|
||||
MXL_CMD_WRITE, cmdSize, &demodIndex, cmdBuff);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
}
|
||||
|
||||
static int send_master_cmd(struct dvb_frontend *fe,
|
||||
@@ -517,14 +524,16 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
demodChanCfg.fecCodeRate = MXL_HYDRA_FEC_AUTO;
|
||||
|
||||
mutex_lock(&state->base->tune_lock);
|
||||
if (time_after(jiffies + msecs_to_jiffies(200), state->base->next_tune))
|
||||
if (time_after(jiffies + msecs_to_jiffies(200),
|
||||
state->base->next_tune))
|
||||
while (time_before(jiffies, state->base->next_tune))
|
||||
msleep(10);
|
||||
state->base->next_tune = jiffies + msecs_to_jiffies(100);
|
||||
state->tuner_in_use = state->tuner;
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_SET_PARAM_CMD, MXL_CMD_WRITE,
|
||||
cmdSize, &demodChanCfg, cmdBuff);
|
||||
stat = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
stat = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
mutex_unlock(&state->base->tune_lock);
|
||||
return stat;
|
||||
}
|
||||
@@ -634,7 +643,7 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct mxl *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 reg[8], reg2[4];
|
||||
u32 reg[8], reg2[4], n = 0, d = 0;
|
||||
int stat;
|
||||
|
||||
*ber = 0;
|
||||
@@ -645,11 +654,12 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
HYDRA_DMD_STATUS_OFFSET(state->demod)),
|
||||
(7 * sizeof(u32)),
|
||||
(u8 *) ®[0]);
|
||||
stat = read_register_block(state,
|
||||
(HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET +
|
||||
HYDRA_DMD_STATUS_OFFSET(state->demod)),
|
||||
(4 * sizeof(u32)),
|
||||
(u8 *) ®2[0]);
|
||||
stat = read_register_block(
|
||||
state,
|
||||
(HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET +
|
||||
HYDRA_DMD_STATUS_OFFSET(state->demod)),
|
||||
(4 * sizeof(u32)),
|
||||
(u8 *) ®2[0]);
|
||||
HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
|
||||
mutex_unlock(&state->base->status_lock);
|
||||
|
||||
@@ -670,9 +680,9 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pr_info("mxl5xx: ber %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
pr_debug("mxl5xx: ber %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6]);
|
||||
pr_info("mxl5xx: ber2 %08x %08x %08x %08x\n",
|
||||
pr_debug("mxl5xx: ber2 %08x %08x %08x %08x\n",
|
||||
reg[0], reg[1], reg[2], reg[3]);
|
||||
//pre_bit_error, pre_bit_count
|
||||
//post_bit_error, post_bit_count;
|
||||
@@ -755,7 +765,7 @@ static int get_frontend(struct dvb_frontend *fe)
|
||||
HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
|
||||
mutex_unlock(&state->base->status_lock);
|
||||
|
||||
pr_info("mxl5xx: freq=%u delsys=%u srate=%u\n",
|
||||
pr_debug("mxl5xx: freq=%u delsys=%u srate=%u\n",
|
||||
freq * 1000, regData[DMD_STANDARD_ADDR],
|
||||
regData[DMD_SYMBOL_RATE_ADDR]);
|
||||
p->symbol_rate = regData[DMD_SYMBOL_RATE_ADDR];
|
||||
@@ -769,7 +779,8 @@ static int get_frontend(struct dvb_frontend *fe)
|
||||
case SYS_DSS:
|
||||
break;
|
||||
case SYS_DVBS2:
|
||||
switch ((MXL_HYDRA_PILOTS_E ) regData[DMD_DVBS2_PILOT_ON_OFF_ADDR]) {
|
||||
switch ((MXL_HYDRA_PILOTS_E )
|
||||
regData[DMD_DVBS2_PILOT_ON_OFF_ADDR]) {
|
||||
case MXL_HYDRA_PILOTS_OFF:
|
||||
p->pilot = PILOT_OFF;
|
||||
break;
|
||||
@@ -780,7 +791,8 @@ static int get_frontend(struct dvb_frontend *fe)
|
||||
break;
|
||||
}
|
||||
case SYS_DVBS:
|
||||
switch ((MXL_HYDRA_MODULATION_E) regData[DMD_MODULATION_SCHEME_ADDR]) {
|
||||
switch ((MXL_HYDRA_MODULATION_E)
|
||||
regData[DMD_MODULATION_SCHEME_ADDR]) {
|
||||
case MXL_HYDRA_MOD_QPSK:
|
||||
p->modulation = QPSK;
|
||||
break;
|
||||
@@ -790,7 +802,8 @@ static int get_frontend(struct dvb_frontend *fe)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch ((MXL_HYDRA_ROLLOFF_E) regData[DMD_SPECTRUM_ROLL_OFF_ADDR]) {
|
||||
switch ((MXL_HYDRA_ROLLOFF_E)
|
||||
regData[DMD_SPECTRUM_ROLL_OFF_ADDR]) {
|
||||
case MXL_HYDRA_ROLLOFF_0_20:
|
||||
p->rolloff = ROLLOFF_20;
|
||||
break;
|
||||
@@ -903,12 +916,14 @@ static int write_fw_segment(struct mxl *state,
|
||||
u32 origSize = 0;
|
||||
u8 *wBufPtr = NULL;
|
||||
u32 blockSize = ((MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH -
|
||||
(MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4;
|
||||
(MXL_HYDRA_I2C_HDR_SIZE +
|
||||
MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4;
|
||||
u8 wMsgBuffer[MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH -
|
||||
(MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)];
|
||||
|
||||
do {
|
||||
size = origSize = (((u32)(dataCount + blockSize)) > totalSize) ?
|
||||
size = origSize =
|
||||
(((u32)(dataCount + blockSize)) > totalSize) ?
|
||||
(totalSize - dataCount) : blockSize;
|
||||
|
||||
if (origSize & 3)
|
||||
@@ -929,8 +944,8 @@ static int write_fw_segment(struct mxl *state,
|
||||
return status;
|
||||
}
|
||||
|
||||
static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr, u32 mbinBufferSize)
|
||||
|
||||
static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr,
|
||||
u32 mbinBufferSize)
|
||||
{
|
||||
int status;
|
||||
u32 index = 0;
|
||||
@@ -955,26 +970,31 @@ static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr, u32 mbinBu
|
||||
__func__, segmentPtr->header.id);
|
||||
return -EINVAL;
|
||||
}
|
||||
segLength = get_big_endian(24, &(segmentPtr->header.len24[0]));
|
||||
segAddress = get_big_endian(32, &(segmentPtr->header.address[0]));
|
||||
segLength = get_big_endian(24,
|
||||
&(segmentPtr->header.len24[0]));
|
||||
segAddress = get_big_endian(32,
|
||||
&(segmentPtr->header.address[0]));
|
||||
|
||||
if (state->base->type == MXL_HYDRA_DEVICE_568) {
|
||||
if ((((segAddress & 0x90760000) == 0x90760000) ||
|
||||
((segAddress & 0x90740000) == 0x90740000)) &&
|
||||
(xcpuFwFlag == MXL_FALSE)) {
|
||||
SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N, 1);
|
||||
SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N,
|
||||
1);
|
||||
msleep(200);
|
||||
write_register(state, 0x90720000, 0);
|
||||
msleep(10);
|
||||
xcpuFwFlag = MXL_TRUE;
|
||||
}
|
||||
status = write_fw_segment(state, segAddress,
|
||||
segLength, (u8 *) segmentPtr->data);
|
||||
segLength,
|
||||
(u8 *) segmentPtr->data);
|
||||
} else {
|
||||
if (((segAddress & 0x90760000) != 0x90760000) &&
|
||||
((segAddress & 0x90740000) != 0x90740000))
|
||||
status = write_fw_segment(state, segAddress,
|
||||
segLength, (u8 *) segmentPtr->data);
|
||||
segLength,
|
||||
(u8 *) segmentPtr->data);
|
||||
}
|
||||
if (status)
|
||||
return status;
|
||||
@@ -1037,14 +1057,17 @@ static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len)
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Disable clock to Baseband, Wideband, SerDes, Alias ext & Transport modules */
|
||||
status = write_register(state, HYDRA_MODULES_CLK_2_REG, HYDRA_DISABLE_CLK_2);
|
||||
/* Disable clock to Baseband, Wideband, SerDes,
|
||||
Alias ext & Transport modules */
|
||||
status = write_register(state, HYDRA_MODULES_CLK_2_REG,
|
||||
HYDRA_DISABLE_CLK_2);
|
||||
if (status)
|
||||
return status;
|
||||
/* Clear Software & Host interrupt status - (Clear on read) */
|
||||
status = read_register(state, HYDRA_PRCM_ROOT_CLK_REG, ®Data);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = do_firmware_download(state, mbin, mbin_len);
|
||||
if (status)
|
||||
return status;
|
||||
@@ -1081,13 +1104,15 @@ static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len)
|
||||
|
||||
pr_info("mxl5xx: Hydra FW alive. Hail!\n");
|
||||
|
||||
/* sometimes register values are wrong shortly after first heart beats */
|
||||
/* sometimes register values are wrong shortly
|
||||
after first heart beats */
|
||||
msleep(50);
|
||||
|
||||
devSkuCfg.skuType = state->base->sku_type;
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DEV_CFG_SKU_CMD, MXL_CMD_WRITE,
|
||||
cmdSize, &devSkuCfg, cmdBuff);
|
||||
status = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
status = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -1117,19 +1142,32 @@ static int cfg_ts_pad_mux(struct mxl *state, MXL_BOOL_E enableSerialTS)
|
||||
case MXL_HYDRA_DEVICE_541S:
|
||||
case MXL_HYDRA_DEVICE_561S:
|
||||
case MXL_HYDRA_DEVICE_581S:
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_20_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_21_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_22_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_23_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_24_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_25_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_26_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_20_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_21_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_22_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_23_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_24_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_25_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_26_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
break;
|
||||
|
||||
case MXL_HYDRA_DEVICE_544:
|
||||
@@ -1313,7 +1351,7 @@ static int enable_tuner(struct mxl *state, u32 tuner, u32 enable)
|
||||
if (!count)
|
||||
return -1;
|
||||
read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val);
|
||||
pr_info("mxl5xx: tuner %u ready = %u\n", tuner , (val >> tuner) & 1);
|
||||
/*pr_info("mxl5xx: tuner %u ready = %u\n", tuner , (val >> tuner) & 1);*/
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -1348,8 +1386,10 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId,
|
||||
{XPT_TS_CLK_PHASE4}, {XPT_TS_CLK_PHASE5},
|
||||
{XPT_TS_CLK_PHASE6}, {XPT_TS_CLK_PHASE7} };
|
||||
MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = {
|
||||
{XPT_LSB_FIRST0}, {XPT_LSB_FIRST1}, {XPT_LSB_FIRST2}, {XPT_LSB_FIRST3},
|
||||
{XPT_LSB_FIRST4}, {XPT_LSB_FIRST5}, {XPT_LSB_FIRST6}, {XPT_LSB_FIRST7} };
|
||||
{XPT_LSB_FIRST0}, {XPT_LSB_FIRST1},
|
||||
{XPT_LSB_FIRST2}, {XPT_LSB_FIRST3},
|
||||
{XPT_LSB_FIRST4}, {XPT_LSB_FIRST5},
|
||||
{XPT_LSB_FIRST6}, {XPT_LSB_FIRST7} };
|
||||
MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = {
|
||||
{XPT_SYNC_FULL_BYTE0}, {XPT_SYNC_FULL_BYTE1},
|
||||
{XPT_SYNC_FULL_BYTE2}, {XPT_SYNC_FULL_BYTE3},
|
||||
@@ -1384,16 +1424,17 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId,
|
||||
MXL_REG_FIELD_T mxl561_xpt_ts_sync[MXL_HYDRA_DEMOD_ID_6] = {
|
||||
{PAD_MUX_DIGIO_25_PINMUX_SEL}, {PAD_MUX_DIGIO_20_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_17_PINMUX_SEL}, {PAD_MUX_DIGIO_11_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_08_PINMUX_SEL}, {PAD_MUX_DIGIO_03_PINMUX_SEL} };
|
||||
{PAD_MUX_DIGIO_08_PINMUX_SEL}, {PAD_MUX_DIGIO_03_PINMUX_SEL}};
|
||||
MXL_REG_FIELD_T mxl561_xpt_ts_valid[MXL_HYDRA_DEMOD_ID_6] = {
|
||||
{PAD_MUX_DIGIO_26_PINMUX_SEL}, {PAD_MUX_DIGIO_19_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_18_PINMUX_SEL}, {PAD_MUX_DIGIO_10_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_09_PINMUX_SEL}, {PAD_MUX_DIGIO_02_PINMUX_SEL} };
|
||||
{PAD_MUX_DIGIO_09_PINMUX_SEL}, {PAD_MUX_DIGIO_02_PINMUX_SEL}};
|
||||
|
||||
demodId = state->base->ts_map[demodId];
|
||||
|
||||
if (MXL_ENABLE == mpegOutParamPtr->enable) {
|
||||
if (mpegOutParamPtr->mpegMode == MXL_HYDRA_MPEG_MODE_PARALLEL) {
|
||||
if (mpegOutParamPtr->mpegMode ==
|
||||
MXL_HYDRA_MPEG_MODE_PARALLEL) {
|
||||
#if 0
|
||||
for (i = MXL_HYDRA_DEMOD_ID_0; i < MXL_HYDRA_DEMOD_MAX; i++) {
|
||||
mxlStatus |= MxLWare_Hydra_UpdateByMnemonic(devId,
|
||||
@@ -1527,11 +1568,12 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId,
|
||||
}
|
||||
|
||||
if (mpegOutParamPtr->mpegMode != MXL_HYDRA_MPEG_MODE_PARALLEL) {
|
||||
status |= update_by_mnemonic(state,
|
||||
xpt_enable_output[demodId].regAddr,
|
||||
xpt_enable_output[demodId].lsbPos,
|
||||
xpt_enable_output[demodId].numOfBits,
|
||||
mpegOutParamPtr->enable);
|
||||
status |=
|
||||
update_by_mnemonic(state,
|
||||
xpt_enable_output[demodId].regAddr,
|
||||
xpt_enable_output[demodId].lsbPos,
|
||||
xpt_enable_output[demodId].numOfBits,
|
||||
mpegOutParamPtr->enable);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -1569,7 +1611,8 @@ static int config_dis(struct mxl *state, u32 id)
|
||||
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DISEQC_CFG_MSG_CMD,
|
||||
MXL_CMD_WRITE, cmdSize, &diseqcMsg, cmdBuff);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
}
|
||||
|
||||
static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg)
|
||||
|
@@ -36,6 +36,8 @@
|
||||
#include "stv090x.h"
|
||||
#include "stv090x_priv.h"
|
||||
|
||||
/* Max transfer size done by I2C transfer functions */
|
||||
#define MAX_XFER_SIZE 64
|
||||
#define ERRCTRL1_DVBS1 0x76
|
||||
#define ERRCTRL1_DVBS2 0x67
|
||||
|
||||
@@ -728,8 +730,16 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8
|
||||
{
|
||||
const struct stv090x_config *config = state->config;
|
||||
int ret;
|
||||
u8 buf[2 + count];
|
||||
struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count };
|
||||
u8 buf[MAX_XFER_SIZE];
|
||||
struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0,
|
||||
.buf = buf, .len = 2 + count };
|
||||
|
||||
if (2 + count > sizeof(buf)) {
|
||||
printk(KERN_WARNING
|
||||
"%s: i2c wr reg=%04x: len=%d is too big!\n",
|
||||
KBUILD_MODNAME, reg, count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf[0] = reg >> 8;
|
||||
buf[1] = reg & 0xff;
|
||||
@@ -2144,7 +2154,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
|
||||
|
||||
u32 reg;
|
||||
s32 car_step, steps, cur_step, dir, freq, timeout_lock;
|
||||
int lock = 0;
|
||||
int lock;
|
||||
|
||||
if (state->srate >= 10000000)
|
||||
timeout_lock = timeout_dmd / 3;
|
||||
@@ -2152,100 +2162,97 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
|
||||
timeout_lock = timeout_dmd / 2;
|
||||
|
||||
lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */
|
||||
if (!lock) {
|
||||
if (state->srate >= 10000000) {
|
||||
if (stv090x_chk_tmg(state)) {
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
|
||||
goto err;
|
||||
lock = stv090x_get_dmdlock(state, timeout_dmd);
|
||||
} else {
|
||||
lock = 0;
|
||||
}
|
||||
} else {
|
||||
if (state->srate <= 4000000)
|
||||
car_step = 1000;
|
||||
else if (state->srate <= 7000000)
|
||||
car_step = 2000;
|
||||
else if (state->srate <= 10000000)
|
||||
car_step = 3000;
|
||||
else
|
||||
car_step = 5000;
|
||||
if (lock)
|
||||
return lock;
|
||||
|
||||
steps = (state->search_range / 1000) / car_step;
|
||||
steps /= 2;
|
||||
steps = 2 * (steps + 1);
|
||||
if (steps < 0)
|
||||
steps = 2;
|
||||
else if (steps > 12)
|
||||
steps = 12;
|
||||
|
||||
cur_step = 1;
|
||||
dir = 1;
|
||||
|
||||
if (!lock) {
|
||||
freq = state->frequency;
|
||||
state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
|
||||
while ((cur_step <= steps) && (!lock)) {
|
||||
if (dir > 0)
|
||||
freq += cur_step * car_step;
|
||||
else
|
||||
freq -= cur_step * car_step;
|
||||
|
||||
/* Setup tuner */
|
||||
if (stv090x_i2c_gate_ctrl(state, 1) < 0)
|
||||
goto err;
|
||||
|
||||
if (state->config->tuner_set_frequency) {
|
||||
if (state->config->tuner_set_frequency(fe, freq) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (state->config->tuner_set_bandwidth) {
|
||||
if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
|
||||
goto err;
|
||||
|
||||
msleep(50);
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 1) < 0)
|
||||
goto err;
|
||||
|
||||
if (state->config->tuner_get_status) {
|
||||
if (state->config->tuner_get_status(fe, ®) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (reg)
|
||||
dprintk(FE_DEBUG, 1, "Tuner phase locked");
|
||||
else
|
||||
dprintk(FE_DEBUG, 1, "Tuner unlocked");
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
|
||||
goto err;
|
||||
|
||||
STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
|
||||
if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
|
||||
goto err;
|
||||
lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
|
||||
|
||||
dir *= -1;
|
||||
cur_step++;
|
||||
}
|
||||
}
|
||||
if (state->srate >= 10000000) {
|
||||
if (stv090x_chk_tmg(state)) {
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
|
||||
goto err;
|
||||
return stv090x_get_dmdlock(state, timeout_dmd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (state->srate <= 4000000)
|
||||
car_step = 1000;
|
||||
else if (state->srate <= 7000000)
|
||||
car_step = 2000;
|
||||
else if (state->srate <= 10000000)
|
||||
car_step = 3000;
|
||||
else
|
||||
car_step = 5000;
|
||||
|
||||
steps = (state->search_range / 1000) / car_step;
|
||||
steps /= 2;
|
||||
steps = 2 * (steps + 1);
|
||||
if (steps < 0)
|
||||
steps = 2;
|
||||
else if (steps > 12)
|
||||
steps = 12;
|
||||
|
||||
cur_step = 1;
|
||||
dir = 1;
|
||||
|
||||
freq = state->frequency;
|
||||
state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
|
||||
while ((cur_step <= steps) && (!lock)) {
|
||||
if (dir > 0)
|
||||
freq += cur_step * car_step;
|
||||
else
|
||||
freq -= cur_step * car_step;
|
||||
|
||||
/* Setup tuner */
|
||||
if (stv090x_i2c_gate_ctrl(state, 1) < 0)
|
||||
goto err;
|
||||
|
||||
if (state->config->tuner_set_frequency) {
|
||||
if (state->config->tuner_set_frequency(fe, freq) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (state->config->tuner_set_bandwidth) {
|
||||
if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
|
||||
goto err;
|
||||
|
||||
msleep(50);
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 1) < 0)
|
||||
goto err;
|
||||
|
||||
if (state->config->tuner_get_status) {
|
||||
if (state->config->tuner_get_status(fe, ®) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (reg)
|
||||
dprintk(FE_DEBUG, 1, "Tuner phase locked");
|
||||
else
|
||||
dprintk(FE_DEBUG, 1, "Tuner unlocked");
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
|
||||
goto err;
|
||||
|
||||
STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
|
||||
if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
|
||||
goto err;
|
||||
lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
|
||||
|
||||
dir *= -1;
|
||||
cur_step++;
|
||||
}
|
||||
return lock;
|
||||
|
||||
err_gateoff:
|
||||
@@ -2661,14 +2668,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
|
||||
return STV090x_RANGEOK;
|
||||
else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))
|
||||
return STV090x_RANGEOK;
|
||||
else
|
||||
return STV090x_OUTOFRANGE; /* Out of Range */
|
||||
} else {
|
||||
} else
|
||||
if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
|
||||
return STV090x_RANGEOK;
|
||||
else
|
||||
return STV090x_OUTOFRANGE;
|
||||
}
|
||||
|
||||
return STV090x_OUTOFRANGE;
|
||||
|
||||
@@ -2787,6 +2789,12 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod
|
||||
aclc = car_loop[i].crl_pilots_off_30;
|
||||
}
|
||||
} else { /* 16APSK and 32APSK */
|
||||
/*
|
||||
* This should never happen in practice, except if
|
||||
* something is really wrong at the car_loop table.
|
||||
*/
|
||||
if (i >= 11)
|
||||
i = 10;
|
||||
if (state->srate <= 3000000)
|
||||
aclc = car_loop_apsk_low[i].crl_pilots_on_2;
|
||||
else if (state->srate <= 7000000)
|
||||
@@ -3435,6 +3443,48 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_set_pls(struct stv090x_state *state, u8 pls_mode, u32 pls_code)
|
||||
{
|
||||
dprintk(FE_DEBUG, 1, "Set PLS code %d (mode %d)", pls_code, pls_mode);
|
||||
if (STV090x_WRITE_DEMOD(state, PLROOT2, (pls_mode << 2) | (pls_code >> 16)) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, PLROOT1, (pls_code >> 8) & 0xff) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code & 0xff) < 0)
|
||||
goto err;
|
||||
return 0;
|
||||
err:
|
||||
dprintk(FE_ERROR, 1, "I/O error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_set_mis(struct stv090x_state *state, u32 mis)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (mis == NO_STREAM_ID_FILTER) {
|
||||
dprintk(FE_DEBUG, 1, "Disable MIS filtering");
|
||||
reg = STV090x_READ_DEMOD(state, PDELCTRL1);
|
||||
STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x00);
|
||||
if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
|
||||
goto err;
|
||||
} else {
|
||||
dprintk(FE_DEBUG, 1, "Enable MIS filtering - %d", mis);
|
||||
reg = STV090x_READ_DEMOD(state, PDELCTRL1);
|
||||
STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x01);
|
||||
if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, ISIENTRY, mis & 0xff) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, ISIBITENA, 0xff) < 0)
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
dprintk(FE_ERROR, 1, "I/O error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef USE_API3
|
||||
static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
|
||||
#else
|
||||
@@ -3443,14 +3493,27 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *props = &fe->dtv_property_cache;
|
||||
|
||||
u32 pls = 1;
|
||||
|
||||
#ifndef USE_API3
|
||||
if (props->frequency == 0)
|
||||
#else
|
||||
return DVBFE_ALGO_SEARCH_INVALID;
|
||||
#endif
|
||||
|
||||
state->delsys = props->delivery_system;
|
||||
switch (props->delivery_system) {
|
||||
case SYS_DSS:
|
||||
state->delsys = STV090x_DSS;
|
||||
break;
|
||||
case SYS_DVBS:
|
||||
state->delsys = STV090x_DVBS1;
|
||||
break;
|
||||
case SYS_DVBS2:
|
||||
state->delsys = STV090x_DVBS2;
|
||||
break;
|
||||
default:
|
||||
return DVBFE_ALGO_SEARCH_INVALID;
|
||||
}
|
||||
#ifndef USE_API3
|
||||
state->frequency = props->frequency;
|
||||
state->srate = props->symbol_rate;
|
||||
@@ -3469,6 +3532,16 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron
|
||||
state->search_range = 5000000;
|
||||
}
|
||||
|
||||
/* Backwards compatibility to "crazy" API.
|
||||
PRBS X root cannot be 0, so this should always work. */
|
||||
if ((props->stream_id != NO_STREAM_ID_FILTER) &&
|
||||
(props->stream_id & 0xffffff00))
|
||||
pls = props->stream_id >> 8;
|
||||
if (props->pls != NO_SCRAMBLING_CODE)
|
||||
pls = props->pls | 0x40000; /* props->pls is always gold code */
|
||||
stv090x_set_pls(state, (pls >> 18) & 3, pls & 0x3ffff);
|
||||
stv090x_set_mis(state, props->stream_id);
|
||||
|
||||
if (stv090x_algo(state) == STV090x_RANGEOK) {
|
||||
dprintk(FE_DEBUG, 1, "Search success!");
|
||||
return DVBFE_ALGO_SEARCH_SUCCESS;
|
||||
@@ -3585,7 +3658,6 @@ static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
|
||||
u32 reg, h, m, l;
|
||||
enum fe_status status;
|
||||
|
||||
@@ -3605,6 +3677,14 @@ static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
|
||||
*ber = ((h << 16) | (m << 8) | l);
|
||||
}
|
||||
#if 0
|
||||
p->pre_bit_error.len = 1;
|
||||
p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_error.stat[0].uvalue = n;
|
||||
p->pre_bit_count.len = 1;
|
||||
p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_count.stat[0].uvalue = d;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3723,6 +3803,9 @@ static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
p->strength.stat[0].uvalue = 1000 * (s64) (s32) str;
|
||||
#ifdef DBVALS
|
||||
*strength = str;
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].uvalue = 10 * (s64) str;
|
||||
#else
|
||||
*strength = (str + 100) * 0xFFFF / 100;
|
||||
#endif
|
||||
@@ -3813,7 +3896,6 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DBVALS
|
||||
*cnr = cnr_db;
|
||||
#endif
|
||||
@@ -3823,7 +3905,7 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
|
||||
static int stv090x_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
u32 reg;
|
||||
@@ -3921,7 +4003,8 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
|
||||
static int stv090x_send_diseqc_burst(struct dvb_frontend *fe,
|
||||
enum fe_sec_mini_cmd burst)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
u32 reg, idle = 0, fifo_full = 1;
|
||||
@@ -4032,12 +4115,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR1);
|
||||
STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
/* power off DiSEqC 1 */
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR2);
|
||||
STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
|
||||
/* check whether path 2 is already sleeping, that is when
|
||||
ADC2 is off */
|
||||
@@ -4056,7 +4139,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
reg = stv090x_read_reg(state, STV090x_STOPCLK2);
|
||||
/* sampling 1 clock */
|
||||
STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
|
||||
@@ -4067,7 +4150,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
break;
|
||||
|
||||
case STV090x_DEMODULATOR_1:
|
||||
@@ -4075,12 +4158,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR3);
|
||||
STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
/* power off DiSEqC 2 */
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR4);
|
||||
STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
|
||||
/* check whether path 1 is already sleeping, that is when
|
||||
ADC1 is off */
|
||||
@@ -4099,7 +4182,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
reg = stv090x_read_reg(state, STV090x_STOPCLK2);
|
||||
/* sampling 2 clock */
|
||||
STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
|
||||
@@ -4110,7 +4193,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -4123,7 +4206,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
|
||||
STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
mutex_unlock(&state->internal->demod_lock);
|
||||
@@ -4131,8 +4214,10 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
|
||||
err_gateoff:
|
||||
stv090x_i2c_gate_ctrl(state, 0);
|
||||
err:
|
||||
goto err;
|
||||
err_unlock:
|
||||
mutex_unlock(&state->internal->demod_lock);
|
||||
err:
|
||||
dprintk(FE_ERROR, 1, "I/O error");
|
||||
return -1;
|
||||
}
|
||||
@@ -4393,7 +4478,7 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_set_tspath(struct stv090x_state *state)
|
||||
static int stv0900_set_tspath(struct stv090x_state *state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
@@ -4643,8 +4728,6 @@ static int stv090x_set_tspath(struct stv090x_state *state)
|
||||
}
|
||||
|
||||
|
||||
printk("TSCFGH resets\n");
|
||||
|
||||
reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
|
||||
@@ -4667,6 +4750,121 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv0903_set_tspath(struct stv090x_state *state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (state->internal->dev_ver >= 0x20) {
|
||||
switch (state->config->ts1_mode) {
|
||||
case STV090x_TSMODE_PARALLEL_PUNCTURED:
|
||||
case STV090x_TSMODE_DVBCI:
|
||||
stv090x_write_reg(state, STV090x_TSGENERAL, 0x00);
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_SERIAL_PUNCTURED:
|
||||
case STV090x_TSMODE_SERIAL_CONTINUOUS:
|
||||
default:
|
||||
stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (state->config->ts1_mode) {
|
||||
case STV090x_TSMODE_PARALLEL_PUNCTURED:
|
||||
case STV090x_TSMODE_DVBCI:
|
||||
stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10);
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_SERIAL_PUNCTURED:
|
||||
case STV090x_TSMODE_SERIAL_CONTINUOUS:
|
||||
default:
|
||||
stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (state->config->ts1_mode) {
|
||||
case STV090x_TSMODE_PARALLEL_PUNCTURED:
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_DVBCI:
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_SERIAL_PUNCTURED:
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_SERIAL_CONTINUOUS:
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (state->config->ts1_clk > 0) {
|
||||
u32 speed;
|
||||
|
||||
switch (state->config->ts1_mode) {
|
||||
case STV090x_TSMODE_PARALLEL_PUNCTURED:
|
||||
case STV090x_TSMODE_DVBCI:
|
||||
default:
|
||||
speed = state->internal->mclk /
|
||||
(state->config->ts1_clk / 4);
|
||||
if (speed < 0x08)
|
||||
speed = 0x08;
|
||||
if (speed > 0xFF)
|
||||
speed = 0xFF;
|
||||
break;
|
||||
case STV090x_TSMODE_SERIAL_PUNCTURED:
|
||||
case STV090x_TSMODE_SERIAL_CONTINUOUS:
|
||||
speed = state->internal->mclk /
|
||||
(state->config->ts1_clk / 32);
|
||||
if (speed < 0x20)
|
||||
speed = 0x20;
|
||||
if (speed > 0xFF)
|
||||
speed = 0xFF;
|
||||
break;
|
||||
}
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
|
||||
goto err;
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dprintk(FE_ERROR, 1, "I/O error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
@@ -4730,8 +4928,13 @@ static int stv090x_init(struct dvb_frontend *fe)
|
||||
goto err;
|
||||
|
||||
#if 0
|
||||
if (stv090x_set_tspath(state) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900) {
|
||||
if (stv0900_set_tspath(state) < 0)
|
||||
goto err;
|
||||
} else {
|
||||
if (stv0903_set_tspath(state) < 0)
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
@@ -4772,23 +4975,26 @@ static int stv090x_setup(struct dvb_frontend *fe)
|
||||
/* Stop Demod */
|
||||
if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0)
|
||||
goto err;
|
||||
if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900)
|
||||
if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)
|
||||
goto err;
|
||||
|
||||
msleep(5);
|
||||
|
||||
/* Set No Tuner Mode */
|
||||
if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0)
|
||||
goto err;
|
||||
if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900)
|
||||
if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)
|
||||
goto err;
|
||||
|
||||
/* I2C repeater OFF */
|
||||
STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);
|
||||
if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0)
|
||||
goto err;
|
||||
if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900)
|
||||
if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)
|
||||
goto err;
|
||||
|
||||
if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
|
||||
goto err;
|
||||
@@ -4848,8 +5054,13 @@ static int stv090x_setup(struct dvb_frontend *fe)
|
||||
if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
|
||||
goto err;
|
||||
|
||||
if (stv090x_set_tspath(state) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900) {
|
||||
if (stv0900_set_tspath(state) < 0)
|
||||
goto err;
|
||||
} else {
|
||||
if (stv0903_set_tspath(state) < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
@@ -4857,8 +5068,8 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
|
||||
u8 xor_value)
|
||||
static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir,
|
||||
u8 value, u8 xor_value)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
u8 reg = 0;
|
||||
@@ -4869,7 +5080,69 @@ int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
|
||||
|
||||
return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
|
||||
}
|
||||
EXPORT_SYMBOL(stv090x_set_gpio);
|
||||
|
||||
static int stv090x_get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u8 tmp;
|
||||
u32 reg = 0;
|
||||
|
||||
if (state->rec_mode == 2) {
|
||||
u32 mc;
|
||||
enum fe_modulation modcod2mod[0x20] = {
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
PSK_8, PSK_8, PSK_8, PSK_8,
|
||||
PSK_8, PSK_8, APSK_16, APSK_16,
|
||||
APSK_16, APSK_16, APSK_16, APSK_16,
|
||||
APSK_32, APSK_32, APSK_32, APSK_32,
|
||||
APSK_32,
|
||||
};
|
||||
enum fe_code_rate modcod2fec[0x20] = {
|
||||
FEC_NONE, FEC_1_4, FEC_1_3, FEC_2_5,
|
||||
FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4,
|
||||
FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10,
|
||||
FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6,
|
||||
FEC_8_9, FEC_9_10, FEC_2_3, FEC_3_4,
|
||||
FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10,
|
||||
FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9,
|
||||
FEC_9_10
|
||||
};
|
||||
mc = state->modcod;
|
||||
p->pilot = (state->pilots & 0x01) ? PILOT_ON : PILOT_OFF;
|
||||
p->modulation = modcod2mod[mc];
|
||||
p->fec_inner = modcod2fec[mc];
|
||||
} else if (state->rec_mode == 1) {
|
||||
reg = STV090x_READ_DEMOD(state, VITCURPUN);
|
||||
switch( reg & 0x1F ) {
|
||||
case 0x0d:
|
||||
p->fec_inner = FEC_1_2;
|
||||
break;
|
||||
case 0x12:
|
||||
p->fec_inner = FEC_2_3;
|
||||
break;
|
||||
case 0x15:
|
||||
p->fec_inner = FEC_3_4;
|
||||
break;
|
||||
case 0x18:
|
||||
p->fec_inner = FEC_5_6;
|
||||
break;
|
||||
case 0x1a:
|
||||
p->fec_inner = FEC_7_8;
|
||||
break;
|
||||
default:
|
||||
p->fec_inner = FEC_NONE;
|
||||
break;
|
||||
}
|
||||
p->rolloff = ROLLOFF_35;
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
@@ -4960,7 +5233,7 @@ static struct dvb_frontend_ops stv090x_ops = {
|
||||
|
||||
.sleep = stv090x_sleep,
|
||||
.get_frontend_algo = stv090x_frontend_algo,
|
||||
.get_frontend = get_frontend,
|
||||
.get_frontend = stv090x_get_frontend,
|
||||
|
||||
.diseqc_send_master_cmd = stv090x_send_diseqc_msg,
|
||||
.diseqc_send_burst = stv090x_send_diseqc_burst,
|
||||
@@ -4976,7 +5249,7 @@ static struct dvb_frontend_ops stv090x_ops = {
|
||||
};
|
||||
|
||||
|
||||
struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
enum stv090x_demodulator demod)
|
||||
{
|
||||
@@ -5030,10 +5303,15 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
}
|
||||
}
|
||||
|
||||
if (state->internal->dev_ver >= 0x30)
|
||||
state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM;
|
||||
|
||||
/* workaround for stuck DiSEqC output */
|
||||
if (config->diseqc_envelope_mode)
|
||||
stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
|
||||
|
||||
config->set_gpio = stv090x_set_gpio;
|
||||
|
||||
dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
|
||||
state->device == STV0900 ? "STV0900" : "STV0903",
|
||||
demod,
|
||||
|
@@ -101,18 +101,18 @@ struct stv090x_config {
|
||||
int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
|
||||
int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
|
||||
void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock);
|
||||
|
||||
/* dir = 0 -> output, dir = 1 -> input/open-drain */
|
||||
int (*set_gpio)(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
|
||||
u8 xor_value);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
extern struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
enum stv090x_demodulator demod);
|
||||
|
||||
/* dir = 0 -> output, dir = 1 -> input/open-drain */
|
||||
extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
|
||||
u8 dir, u8 value, u8 xor_value);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
@@ -123,12 +123,6 @@ static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
|
||||
u8 opd, u8 value, u8 xor_value)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_DVB_STV090x */
|
||||
|
||||
#endif /* __STV090x_H */
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Driver for the ST STV0910 DVB-S/S2 demodulator.
|
||||
*
|
||||
* Copyright (C) 2014-2015 Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Copyright (C) 2014-2016 Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* developed for Digital Devices GmbH
|
||||
*
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "stv0910_regs.h"
|
||||
|
||||
|
||||
#define EXT_CLOCK 30000000
|
||||
#define TUNING_DELAY 200
|
||||
#define BER_SRC_S 0x20
|
||||
#define BER_SRC_S2 0x20
|
||||
@@ -123,9 +124,17 @@ struct stv {
|
||||
u32 Pilots;
|
||||
enum FE_STV0910_RollOff FERollOff;
|
||||
|
||||
int isStandardBroadcast;
|
||||
int isVCM;
|
||||
|
||||
u32 CurScramblingCode;
|
||||
u32 ScramblingCode;
|
||||
|
||||
u32 LastBERNumerator;
|
||||
u32 LastBERDenominator;
|
||||
u8 BERScale;
|
||||
|
||||
u8 VTH[6];
|
||||
};
|
||||
|
||||
struct SInitTable {
|
||||
@@ -193,6 +202,19 @@ static int read_regs(struct stv *state, u16 reg, u8 *val, int len)
|
||||
reg, val, len);
|
||||
}
|
||||
|
||||
static int write_shared_reg(struct stv *state, u16 reg, u8 mask, u8 val)
|
||||
{
|
||||
int status;
|
||||
u8 tmp;
|
||||
|
||||
mutex_lock(&state->base->reg_lock);
|
||||
status = read_reg(state, reg, &tmp);
|
||||
if (!status)
|
||||
status = write_reg(state, reg, (tmp & ~mask) | (val & mask));
|
||||
mutex_unlock(&state->base->reg_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct SLookup S1_SN_Lookup[] = {
|
||||
{ 0, 9242 }, /*C/N= 0dB*/
|
||||
{ 05, 9105 }, /*C/N=0.5dB*/
|
||||
@@ -452,24 +474,45 @@ static int GetCurSymbolRate(struct stv *state, u32 *pSymbolRate)
|
||||
|
||||
static int GetSignalParameters(struct stv *state)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
if (!state->Started)
|
||||
return -1;
|
||||
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
u8 tmp;
|
||||
u8 rolloff;
|
||||
|
||||
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp);
|
||||
state->ModCod = (enum FE_STV0910_ModCod) ((tmp & 0x7c) >> 2);
|
||||
state->Pilots = (tmp & 0x01) != 0;
|
||||
state->FECType = (enum DVBS2_FECType) ((tmp & 0x02) >> 1);
|
||||
|
||||
#if 0
|
||||
read_reg(state, RSTV0910_P2_TMGOBS + state->regoff, &rolloff);
|
||||
rolloff = rolloff >> 6;
|
||||
state->FERollOff = (enum FE_STV0910_RollOff) rolloff;
|
||||
|
||||
#endif
|
||||
} else if (state->ReceiveMode == Mode_DVBS) {
|
||||
/* todo */
|
||||
read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp);
|
||||
state->PunctureRate = FEC_NONE;
|
||||
switch (tmp & 0x1F) {
|
||||
case 0x0d:
|
||||
state->PunctureRate = FEC_1_2;
|
||||
break;
|
||||
case 0x12:
|
||||
state->PunctureRate = FEC_2_3;
|
||||
break;
|
||||
case 0x15:
|
||||
state->PunctureRate = FEC_3_4;
|
||||
break;
|
||||
case 0x18:
|
||||
state->PunctureRate = FEC_5_6;
|
||||
break;
|
||||
case 0x1A:
|
||||
state->PunctureRate = FEC_7_8;
|
||||
break;
|
||||
}
|
||||
state->isVCM = 0;
|
||||
state->isStandardBroadcast = 1;
|
||||
state->FERollOff = FE_SAT_35;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -485,18 +528,20 @@ static int TrackingOptimization(struct stv *state)
|
||||
|
||||
switch (state->ReceiveMode) {
|
||||
case Mode_DVBS:
|
||||
tmp |= 0x40; break;
|
||||
tmp |= 0x40;
|
||||
break;
|
||||
case Mode_DVBS2:
|
||||
tmp |= 0x80; break;
|
||||
tmp |= 0x80;
|
||||
break;
|
||||
default:
|
||||
tmp |= 0xC0; break;
|
||||
tmp |= 0xC0;
|
||||
break;
|
||||
}
|
||||
write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, tmp);
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
/* force to PRE BCH Rate */
|
||||
write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff,
|
||||
BER_SRC_S2 | state->BERScale);
|
||||
/*Disable Reed-Solomon */
|
||||
write_shared_reg(state, RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, 0x03);
|
||||
|
||||
if (state->FECType == DVBS2_64K) {
|
||||
u8 aclc = get_optim_cloop(state, state->ModCod,
|
||||
@@ -523,29 +568,6 @@ static int TrackingOptimization(struct stv *state)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state->ReceiveMode == Mode_DVBS) {
|
||||
u8 tmp;
|
||||
|
||||
read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp);
|
||||
state->PunctureRate = FEC_NONE;
|
||||
switch (tmp & 0x1F) {
|
||||
case 0x0d:
|
||||
state->PunctureRate = FEC_1_2;
|
||||
break;
|
||||
case 0x12:
|
||||
state->PunctureRate = FEC_2_3;
|
||||
break;
|
||||
case 0x15:
|
||||
state->PunctureRate = FEC_3_4;
|
||||
break;
|
||||
case 0x18:
|
||||
state->PunctureRate = FEC_5_6;
|
||||
break;
|
||||
case 0x1A:
|
||||
state->PunctureRate = FEC_7_8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -558,7 +580,7 @@ static s32 TableLookup(struct SLookup *Table,
|
||||
int i;
|
||||
s32 RegDiff;
|
||||
|
||||
// Assumes Table[0].RegValue > Table[imax].RegValue
|
||||
/* Assumes Table[0].RegValue > Table[imax].RegValue */
|
||||
if( RegValue >= Table[0].RegValue )
|
||||
Value = Table[0].Value;
|
||||
else if( RegValue <= Table[imax].RegValue )
|
||||
@@ -686,11 +708,12 @@ static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType)
|
||||
return 64800;
|
||||
}
|
||||
|
||||
static int GetBitErrorRateS2(struct stv *state, u32 *BERNumerator,
|
||||
static int GetBitErrorRateS2(struct stv *state,
|
||||
u32 *BERNumerator,
|
||||
u32 *BERDenominator)
|
||||
{
|
||||
u8 Regs[3];
|
||||
|
||||
|
||||
int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff,
|
||||
Regs, 3);
|
||||
|
||||
@@ -828,12 +851,118 @@ static int Stop(struct stv *state)
|
||||
}
|
||||
|
||||
|
||||
static int init_search_param(struct stv *state)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp);
|
||||
tmp |= 0x20; // Filter_en (no effect if SIS=non-MIS
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, &tmp);
|
||||
tmp &= ~0x02; // frame mode = 0
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, tmp);
|
||||
|
||||
write_reg(state, RSTV0910_P2_UPLCCST0 + state->regoff, 0xe0);
|
||||
write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0x00);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, &tmp);
|
||||
tmp &= ~0x01; // nosync = 0, in case next signal is standard TS
|
||||
write_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSCFGL + state->regoff, &tmp);
|
||||
tmp &= ~0x04; // embindvb = 0
|
||||
write_reg(state, RSTV0910_P2_TSCFGL + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, &tmp);
|
||||
tmp &= ~0x80; // syncbyte = 0
|
||||
write_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, &tmp);
|
||||
tmp &= ~0x08; // token = 0
|
||||
write_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, &tmp);
|
||||
tmp &= ~0x30; // hysteresis threshold = 0
|
||||
write_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, &tmp);
|
||||
tmp = (tmp & ~0x30) | 0x10; // isi obs mode = 1, observe min ISI
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int EnablePunctureRate(struct stv *state, enum fe_code_rate rate)
|
||||
{
|
||||
switch(rate) {
|
||||
case FEC_1_2:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x01);
|
||||
case FEC_2_3:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x02);
|
||||
case FEC_3_4:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x04);
|
||||
case FEC_5_6:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x08);
|
||||
case FEC_7_8:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x20);
|
||||
case FEC_NONE:
|
||||
default:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2f);
|
||||
}
|
||||
}
|
||||
|
||||
static int set_vth_default(struct stv *state)
|
||||
{
|
||||
state->VTH[0] = 0xd7;
|
||||
state->VTH[1] = 0x85;
|
||||
state->VTH[2] = 0x58;
|
||||
state->VTH[3] = 0x3a;
|
||||
state->VTH[4] = 0x34;
|
||||
state->VTH[5] = 0x28;
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->VTH[0]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->VTH[1]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->VTH[2]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->VTH[3]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->VTH[4]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->VTH[5]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_vth(struct stv *state)
|
||||
{
|
||||
static struct SLookup VTHLookupTable[] = {
|
||||
{250, 8780}, /*C/N=1.5dB*/
|
||||
{100, 7405}, /*C/N=4.5dB*/
|
||||
{40, 6330}, /*C/N=6.5dB*/
|
||||
{12, 5224}, /*C/N=8.5dB*/
|
||||
{5, 4236} /*C/N=10.5dB*/
|
||||
};
|
||||
int i;
|
||||
u8 tmp[2];
|
||||
int status = read_regs(state, RSTV0910_P2_NNOSDATAT1 + state->regoff, tmp, 2);
|
||||
u16 RegValue = (tmp[0] << 8) | tmp[1];
|
||||
s32 vth = TableLookup(VTHLookupTable, ARRAY_SIZE(VTHLookupTable), RegValue);
|
||||
|
||||
for (i = 0; i < 6; i += 1)
|
||||
if (state->VTH[i] > vth)
|
||||
state->VTH[i] = vth;
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->VTH[0]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->VTH[1]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->VTH[2]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->VTH[3]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->VTH[4]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->VTH[5]);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
{
|
||||
s32 Freq;
|
||||
u8 regDMDCFGMD;
|
||||
u16 symb;
|
||||
|
||||
u32 ScramblingCode = 1;
|
||||
|
||||
if (p->symbol_rate < 100000 || p->symbol_rate > 70000000)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -844,6 +973,34 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
if (state->Started)
|
||||
write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C);
|
||||
|
||||
init_search_param(state);
|
||||
|
||||
if (p->stream_id != NO_STREAM_ID_FILTER) {
|
||||
/* Backwards compatibility to "crazy" API.
|
||||
PRBS X root cannot be 0, so this should always work.
|
||||
*/
|
||||
if (p->stream_id & 0xffffff00)
|
||||
ScramblingCode = p->stream_id >> 8;
|
||||
write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff, p->stream_id & 0xff);
|
||||
write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0xff);
|
||||
//pr_info("ID=%08x\n", p->stream_id & 0xff);
|
||||
}
|
||||
|
||||
/* props->pls is always gold code ! */
|
||||
if (p->pls != NO_SCRAMBLING_CODE)
|
||||
ScramblingCode = p->pls | 0x40000;
|
||||
|
||||
if (ScramblingCode != state->CurScramblingCode) {
|
||||
write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff,
|
||||
ScramblingCode & 0xff);
|
||||
write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff,
|
||||
(ScramblingCode >> 8) & 0xff);
|
||||
write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff,
|
||||
(ScramblingCode >> 16) & 0x07);
|
||||
state->CurScramblingCode = ScramblingCode;
|
||||
//pr_info("PLS=%08x\n", ScramblingCode);
|
||||
}
|
||||
|
||||
if (p->symbol_rate <= 1000000) { /*SR <=1Msps*/
|
||||
state->DemodTimeout = 3000;
|
||||
state->FecTimeout = 2000;
|
||||
@@ -852,7 +1009,7 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
state->FecTimeout = 1300;
|
||||
} else if (p->symbol_rate <= 5000000) { /*2Msps< SR <=5Msps*/
|
||||
state->DemodTimeout = 1000;
|
||||
state->FecTimeout = 650;
|
||||
state->FecTimeout = 650;
|
||||
} else if (p->symbol_rate <= 10000000) { /*5Msps< SR <=10Msps*/
|
||||
state->DemodTimeout = 700;
|
||||
state->FecTimeout = 350;
|
||||
@@ -879,25 +1036,43 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ®DMDCFGMD);
|
||||
write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff,
|
||||
regDMDCFGMD |= 0xC0);
|
||||
|
||||
write_shared_reg(state, RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, 0x00);
|
||||
|
||||
/* Disable DSS */
|
||||
write_reg(state, RSTV0910_P2_FECM + state->regoff, 0x00);
|
||||
write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2F);
|
||||
|
||||
EnablePunctureRate(state, FEC_NONE);
|
||||
|
||||
/* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA*/
|
||||
write_reg(state, RSTV0910_P2_ACLC2S2Q + state->regoff, 0x0B);
|
||||
write_reg(state, RSTV0910_P2_ACLC2S28 + state->regoff, 0x0A);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S2Q + state->regoff, 0x84);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S28 + state->regoff, 0x84);
|
||||
write_reg(state, RSTV0910_P2_CARHDR + state->regoff, 0x1C);
|
||||
/* Reset demod */
|
||||
write_reg(state, RSTV0910_P2_CARFREQ + state->regoff, 0x79);
|
||||
|
||||
write_reg(state, RSTV0910_P2_ACLC2S216A + state->regoff, 0x29);
|
||||
write_reg(state, RSTV0910_P2_ACLC2S232A + state->regoff, 0x09);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S216A + state->regoff, 0x84);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S232A + state->regoff, 0x84);
|
||||
|
||||
/* Reset CAR3, bug DVBS2->DVBS1 lock*/
|
||||
/* Note: The bit is only pulsed -> no lock on shared register needed */
|
||||
write_reg(state, RSTV0910_TSTRES0, state->nr ? 0x04 : 0x08);
|
||||
write_reg(state, RSTV0910_TSTRES0, 0);
|
||||
|
||||
set_vth_default(state);
|
||||
|
||||
/* Reset demod */
|
||||
write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F);
|
||||
|
||||
write_reg(state, RSTV0910_P2_CARCFG + state->regoff, 0x46);
|
||||
|
||||
Freq = (state->SearchRange / 2000) + 600;
|
||||
if (p->symbol_rate <= 5000000)
|
||||
Freq -= (600 + 80);
|
||||
Freq = (state->SearchRange / 2000) + 80;
|
||||
else
|
||||
Freq = (state->SearchRange / 2000) + 1600;
|
||||
Freq = (Freq << 16) / (state->base->mclk / 1000);
|
||||
|
||||
write_reg(state, RSTV0910_P2_CFRUP1 + state->regoff,
|
||||
@@ -955,19 +1130,29 @@ static int probe(struct stv *state)
|
||||
/* Configure the I2C repeater to off */
|
||||
write_reg(state, RSTV0910_P2_I2CRPT, 0x24);
|
||||
/* Set the I2C to oversampling ratio */
|
||||
write_reg(state, RSTV0910_I2CCFG, 0x88);
|
||||
write_reg(state, RSTV0910_I2CCFG, 0x88); /* state->i2ccfg */
|
||||
|
||||
write_reg(state, RSTV0910_OUTCFG, 0x00); /* OUTCFG */
|
||||
write_reg(state, RSTV0910_PADCFG, 0x05); /* RF AGC Pads Dev = 05 */
|
||||
write_reg(state, RSTV0910_PADCFG, 0x05); /* RFAGC Pads Dev = 05 */
|
||||
write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */
|
||||
write_reg(state, RSTV0910_TSGENERAL, state->tsgeneral); /* TSGENERAL */
|
||||
write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */
|
||||
write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */
|
||||
|
||||
|
||||
write_reg(state, RSTV0910_P1_CAR3CFG, 0x02);
|
||||
write_reg(state, RSTV0910_P2_CAR3CFG, 0x02);
|
||||
write_reg(state, RSTV0910_P1_DMDCFG4, 0x04);
|
||||
write_reg(state, RSTV0910_P2_DMDCFG4, 0x04);
|
||||
|
||||
write_reg(state, RSTV0910_TSTRES0, 0x80); /* LDPC Reset */
|
||||
write_reg(state, RSTV0910_TSTRES0, 0x00);
|
||||
|
||||
write_reg(state, RSTV0910_P1_TSPIDFLT1, 0x00);
|
||||
write_reg(state, RSTV0910_P2_TSPIDFLT1, 0x00);
|
||||
|
||||
write_reg(state, RSTV0910_P1_TMGCFG2, 0x80);
|
||||
write_reg(state, RSTV0910_P2_TMGCFG2, 0x80);
|
||||
|
||||
set_mclock(state, 135000000);
|
||||
|
||||
/* TS output */
|
||||
@@ -1054,12 +1239,31 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int get_frequency_offset(struct stv *state, s32 *off)
|
||||
{
|
||||
u8 cfr0, cfr1, cfr2;
|
||||
s32 derot;
|
||||
|
||||
read_reg(state, RSTV0910_P2_CFR2 + state->regoff, &cfr2);
|
||||
read_reg(state, RSTV0910_P2_CFR1 + state->regoff, &cfr1);
|
||||
read_reg(state, RSTV0910_P2_CFR0 + state->regoff, &cfr0);
|
||||
|
||||
derot = ((u32) cfr2 << 16) | ((u32)cfr1 << 8) | cfr0;
|
||||
if (derot & (1<<23))
|
||||
derot |= 0xFF000000;
|
||||
*off = - (s32) (((s64) derot * (s64) state->base->mclk) >> 24);
|
||||
//pr_info("foff = %d\n", *off);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct stv *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u8 tmp;
|
||||
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
u32 mc;
|
||||
enum fe_modulation modcod2mod[0x20] = {
|
||||
@@ -1118,6 +1322,28 @@ static int get_frontend(struct dvb_frontend *fe)
|
||||
}
|
||||
|
||||
|
||||
static int ManageMatypeInfo(struct stv *state)
|
||||
{
|
||||
if (!state->Started)
|
||||
return -1;
|
||||
if (state->ReceiveMode == Mode_DVBS2 ) {
|
||||
u8 BBHeader[2];
|
||||
|
||||
read_regs(state, RSTV0910_P2_MATSTR1 + state->regoff,
|
||||
BBHeader, 2);
|
||||
state->FERollOff =
|
||||
(enum FE_STV0910_RollOff) (BBHeader[0] & 0x03);
|
||||
state->isVCM = (BBHeader[0] & 0x10) == 0;
|
||||
state->isStandardBroadcast = (BBHeader[0] & 0xFC) == 0xF0;
|
||||
} else if (state->ReceiveMode == Mode_DVBS) {
|
||||
state->isVCM = 0;
|
||||
state->isStandardBroadcast = 1;
|
||||
state->FERollOff = FE_SAT_35;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int read_snr(struct dvb_frontend *fe, u16 *snr);
|
||||
static int read_signal_strength(struct dvb_frontend *fe, u16 *strength);
|
||||
static int read_ber(struct dvb_frontend *fe, u32 *ber);
|
||||
@@ -1125,13 +1351,15 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber);
|
||||
static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
{
|
||||
struct stv *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u8 DmdState = 0;
|
||||
u8 DStatus = 0;
|
||||
enum ReceiveMode CurReceiveMode = Mode_None;
|
||||
u32 FECLock = 0;
|
||||
u16 val;
|
||||
u32 ber;
|
||||
s32 foff;
|
||||
|
||||
get_frequency_offset(state, &foff);
|
||||
|
||||
read_signal_strength(fe, &val);
|
||||
|
||||
@@ -1140,24 +1368,42 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
read_ber(fe, &ber);
|
||||
|
||||
read_reg(state, RSTV0910_P2_DMDSTATE + state->regoff, &DmdState);
|
||||
|
||||
if (DmdState & 0x40) {
|
||||
read_reg(state, RSTV0910_P2_DSTATUS + state->regoff, &DStatus);
|
||||
read_reg(state, RSTV0910_P2_DSTATUS + state->regoff,
|
||||
&DStatus);
|
||||
if (DStatus & 0x08)
|
||||
CurReceiveMode = (DmdState & 0x20) ?
|
||||
Mode_DVBS : Mode_DVBS2;
|
||||
}
|
||||
if (CurReceiveMode == Mode_None) {
|
||||
set_vth(state);
|
||||
//if( Time >= m_DemodTimeout ) *pLockStatus = NEVER_LOCK;
|
||||
*status = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*status |= 0x0f;
|
||||
if (state->ReceiveMode == Mode_None) {
|
||||
state->ReceiveMode = CurReceiveMode;
|
||||
state->DemodLockTime = jiffies;
|
||||
state->FirstTimeLock = 1;
|
||||
|
||||
GetSignalParameters(state);
|
||||
TrackingOptimization(state);
|
||||
|
||||
#if 0
|
||||
if( CurReceiveMode == Mode_DVBS2 && m_bPilots
|
||||
&& ( m_ModCod == FE_8PSK_23 || m_ModCod == FE_8PSK_35) )
|
||||
{
|
||||
LONG C_N;
|
||||
CHK_ERROR(GetSignalToNoise(&C_N));
|
||||
if( C_N < 80 )
|
||||
{
|
||||
CHK_ERROR(WriteReg(RSTV0910_P2_CARHDR + m_DemodOffset , 0x04));
|
||||
CHK_ERROR(WriteReg(RSTV0910_P2_BCLC2S28 + m_DemodOffset , 0x31));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
write_reg(state, RSTV0910_P2_TSCFGH + state->regoff,
|
||||
state->tscfgh);
|
||||
usleep_range(3000, 4000);
|
||||
@@ -1183,6 +1429,7 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
}
|
||||
|
||||
if (!FECLock)
|
||||
//if( Time >= m_DemodLockTime + m_FecTimeout ) *pLockStatus = NEVER_LOCK;
|
||||
return 0;
|
||||
|
||||
*status |= 0x10;
|
||||
@@ -1191,10 +1438,23 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
u8 tmp;
|
||||
|
||||
state->FirstTimeLock = 0;
|
||||
GetSignalParameters(state);
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
/* FSTV0910_P2_MANUALSX_ROLLOFF,
|
||||
ManageMatypeInfo(state);
|
||||
|
||||
#if 0
|
||||
ULONG Bitrate;
|
||||
CSTV0910::GetBitrate(&Bitrate);
|
||||
BYTE newTSSPEED = (Bitrate > 67000000) ? 0x30 : 0x40;
|
||||
if (newTSSPEED != m_TSSPEED)
|
||||
{
|
||||
KdPrintEx((MSG_INFO "_%d " __FUNCTION__ " TSSPEED = %02X\n", m_Instance, newTSSPEED));
|
||||
CHK_ERROR(WriteReg(RSTV0910_P2_TSSPEED + m_DemodOffset, newTSSPEED));
|
||||
m_TSSPEED = newTSSPEED;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
/* FSTV0910_P2_MANUALSX_ROLLOFF,
|
||||
FSTV0910_P2_MANUALS2_ROLLOFF = 0 */
|
||||
state->DEMOD &= ~0x84;
|
||||
write_reg(state, RSTV0910_P2_DEMOD + state->regoff,
|
||||
@@ -1203,11 +1463,13 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
&tmp);
|
||||
/*reset DVBS2 packet delinator error counter */
|
||||
tmp |= 0x40;
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff,
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 +
|
||||
state->regoff,
|
||||
tmp);
|
||||
/*reset DVBS2 packet delinator error counter */
|
||||
tmp &= ~0x40;
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff,
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 +
|
||||
state->regoff,
|
||||
tmp);
|
||||
|
||||
state->BERScale = 2;
|
||||
@@ -1230,8 +1492,25 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
infinit error count mode )*/
|
||||
write_reg(state, RSTV0910_P2_ERRCTRL2 + state->regoff, 0xc1);
|
||||
|
||||
TrackingOptimization(state);
|
||||
set_vth_default(state);
|
||||
if (state->ReceiveMode == Mode_DVBS)
|
||||
EnablePunctureRate(state, state->PunctureRate);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if( m_isVCM )
|
||||
{
|
||||
// Use highest signaled ModCod for quality
|
||||
BYTE tmp;
|
||||
CHK_ERROR(ReadReg(RSTV0910_P2_DMDMODCOD +
|
||||
m_DemodOffset,&tmp));
|
||||
FE_STV0910_ModCod ModCod =
|
||||
FE_STV0910_ModCod((tmp & 0x7c) >> 2);
|
||||
|
||||
if( ModCod > m_ModCod )
|
||||
m_ModCod = ModCod;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1439,24 +1718,21 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
{
|
||||
struct stv *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u8 Agc1, Agc0;
|
||||
u8 Reg[2];
|
||||
s32 bbgain;
|
||||
s32 Power = 0;
|
||||
int i;
|
||||
|
||||
read_regs(state, RSTV0910_P2_AGCIQIN1 + state->regoff, Reg, 2);
|
||||
//KdPrintEx((MSG_INFO "_%d " __FUNCTION__ " AGCIQIN1 = %02x%02x\n",m_Instance,Reg[0],Reg[1]));
|
||||
|
||||
*strength = (((u32) Reg[0]) << 8) | Reg[1];
|
||||
|
||||
for (i = 0; i < 5; i += 1) {
|
||||
read_regs(state, RSTV0910_P2_POWERI + state->regoff, Reg, 2);
|
||||
Power += (u32) Reg[0] * (u32) Reg[0] + (u32) Reg[1] * (u32) Reg[1];
|
||||
Power += (u32) Reg[0] * (u32) Reg[0] +
|
||||
(u32) Reg[1] * (u32) Reg[1];
|
||||
msleep(3);
|
||||
}
|
||||
Power /= 5;
|
||||
|
||||
bbgain = (465 - Log10x100(Power)) * 10;
|
||||
|
||||
if (fe->ops.tuner_ops.get_rf_strength)
|
||||
@@ -1464,7 +1740,6 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
else
|
||||
*strength = 0;
|
||||
|
||||
printk("pwr = %d bb = %d str = %u\n", Power, bbgain, *strength);
|
||||
if (bbgain < (s32) *strength)
|
||||
*strength -= bbgain;
|
||||
else
|
||||
@@ -1473,7 +1748,8 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].uvalue = 10 * (s64) (s16) *strength - 108750;
|
||||
|
||||
|
||||
/* *strength is in hundredth dBuv, uvalue is in thousandth dBm */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1550,6 +1826,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c,
|
||||
state->SearchRange = 16000000;
|
||||
state->DEMOD = 0x10; /* Inversion : Auto with reset to 0 */
|
||||
state->ReceiveMode = Mode_None;
|
||||
state->CurScramblingCode = NO_SCRAMBLING_CODE;
|
||||
|
||||
base = match_base(i2c, cfg->adr);
|
||||
if (base) {
|
||||
@@ -1586,5 +1863,5 @@ fail:
|
||||
EXPORT_SYMBOL_GPL(stv0910_attach);
|
||||
|
||||
MODULE_DESCRIPTION("STV0910 driver");
|
||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||
MODULE_AUTHOR("Ralph und Marcus Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -105,20 +105,20 @@ static int read_regs(struct stv *state, u8 reg, u8 *val, int len)
|
||||
return i2c_read(state->i2c, state->adr, ®, 1, val, len);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void dump_regs(struct stv *state)
|
||||
{
|
||||
u8 d[11], *c = &state->reg[0];
|
||||
|
||||
read_regs(state, 0, d, 11);
|
||||
#if 0
|
||||
pr_info("stv6111_regs = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
|
||||
d[8], d[9], d[10]);
|
||||
pr_info("reg[] = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
|
||||
c[8], c[9], c[10]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static int wait_for_call_done(struct stv *state, u8 mask)
|
||||
{
|
||||
@@ -184,7 +184,9 @@ static int attach_init(struct stv *state)
|
||||
{
|
||||
if (write_regs(state, 0, 11))
|
||||
return -1;
|
||||
#if 0
|
||||
dump_regs(state);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -299,7 +301,9 @@ static int set_lof(struct stv *state, u32 LocalFrequency, u32 CutOffFrequency)
|
||||
|
||||
state->Frequency = Frequency;
|
||||
|
||||
#if 0
|
||||
dump_regs(state);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -330,39 +334,6 @@ static int get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 AGC_Gain[] = {
|
||||
000, /* 0.0 */
|
||||
000, /* 0.1 */
|
||||
1000, /* 0.2 */
|
||||
2000, /* 0.3 */
|
||||
3000, /* 0.4 */
|
||||
4000, /* 0.5 */
|
||||
5000, /* 0.6 */
|
||||
6000, /* 0.7 */
|
||||
7000, /* 0.8 */
|
||||
14000, /* 0.9 */
|
||||
20000, /* 1.0 */
|
||||
27000, /* 1.1 */
|
||||
32000, /* 1.2 */
|
||||
37000, /* 1.3 */
|
||||
42000, /* 1.4 */
|
||||
47000, /* 1.5 */
|
||||
50000, /* 1.6 */
|
||||
53000, /* 1.7 */
|
||||
56000, /* 1.8 */
|
||||
58000, /* 1.9 */
|
||||
60000, /* 2.0 */
|
||||
62000, /* 2.1 */
|
||||
63000, /* 2.2 */
|
||||
64000, /* 2.3 */
|
||||
64500, /* 2.4 */
|
||||
65000, /* 2.5 */
|
||||
65500, /* 2.6 */
|
||||
66000, /* 2.7 */
|
||||
66500, /* 2.8 */
|
||||
67000, /* 2.9 */
|
||||
};
|
||||
|
||||
struct SLookup {
|
||||
s16 Value;
|
||||
u16 RegValue;
|
||||
@@ -618,7 +589,6 @@ static struct SLookup Gain_Channel_AGC_IIP3_LookUp[] = {
|
||||
{ 1325 , 0xFF00 },
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
static s32 TableLookup(struct SLookup *Table, int TableSize, u16 RegValue)
|
||||
{
|
||||
|
Reference in New Issue
Block a user