Merge branch 'internal'

This commit is contained in:
mvoelkel
2016-08-04 01:00:35 +02:00
26 changed files with 4170 additions and 1376 deletions

View File

@@ -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);

View File

@@ -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__);

View File

@@ -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 *) &reg[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 *) &reg2[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 *) &reg2[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, &regData);
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)

View File

@@ -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, &reg) < 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, &reg) < 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,

View File

@@ -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 */

View File

@@ -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, &regDMDCFGMD);
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

View File

@@ -105,20 +105,20 @@ static int read_regs(struct stv *state, u8 reg, u8 *val, int len)
return i2c_read(state->i2c, state->adr, &reg, 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)
{