Commit d105d083 authored by Daniel Scheller's avatar Daniel Scheller Committed by Mauro Carvalho Chehab

media: dvb-frontends/stv0367: improve QAM fe_status

While cab_state->state gives a quite accurate indication of the demod
signal status, it might be incorrect if cab_algo() wasn't able to
determine the exact status, with cab_algo() being the only place where
this status was updated from, and it is only called upon tuning to new
parameters passed to set_frontend(). Thus, the status will be wrong
until the demod is retuned. With the cab_signal_type parsing in
read_status(), this results in unusual fe_states like FE_HAS_SIGNAL |
FE_HAS_CARRIER | FE_HAS_LOCK, which, while userspace applications check
for FE_HAS_LOCK and work fine, leads to missing CNR or UCB stats.

Fix this by re-reading CAB_FSM_STATUS and updating cab_state->state() in
read_status(). While at it, refactor the fsm/qamfeclock and the
fsm->signaltype parsing into separate functions to make things cleaner
and deduplicate code. Also, assume full QAM FEC lock equals full
FE_STATUS.
Signed-off-by: default avatarDaniel Scheller <d.scheller@gmx.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 552636be
...@@ -2149,6 +2149,71 @@ static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz) ...@@ -2149,6 +2149,71 @@ static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz)
return regsym; return regsym;
} }
static u32 stv0367cab_fsm_status(struct stv0367_state *state)
{
return stv0367_readbits(state, F367CAB_FSM_STATUS);
}
static u32 stv0367cab_qamfec_lock(struct stv0367_state *state)
{
return stv0367_readbits(state,
(state->cab_state->qamfec_status_reg ?
state->cab_state->qamfec_status_reg :
F367CAB_QAMFEC_LOCK));
}
static
enum stv0367_cab_signal_type stv0367cab_fsm_signaltype(u32 qam_fsm_status)
{
enum stv0367_cab_signal_type signaltype = FE_CAB_NOAGC;
switch (qam_fsm_status) {
case 1:
signaltype = FE_CAB_NOAGC;
break;
case 2:
signaltype = FE_CAB_NOTIMING;
break;
case 3:
signaltype = FE_CAB_TIMINGOK;
break;
case 4:
signaltype = FE_CAB_NOCARRIER;
break;
case 5:
signaltype = FE_CAB_CARRIEROK;
break;
case 7:
signaltype = FE_CAB_NOBLIND;
break;
case 8:
signaltype = FE_CAB_BLINDOK;
break;
case 10:
signaltype = FE_CAB_NODEMOD;
break;
case 11:
signaltype = FE_CAB_DEMODOK;
break;
case 12:
signaltype = FE_CAB_DEMODOK;
break;
case 13:
signaltype = FE_CAB_NODEMOD;
break;
case 14:
signaltype = FE_CAB_NOBLIND;
break;
case 15:
signaltype = FE_CAB_NOSIGNAL;
break;
default:
break;
}
return signaltype;
}
static int stv0367cab_read_status(struct dvb_frontend *fe, static int stv0367cab_read_status(struct dvb_frontend *fe,
enum fe_status *status) enum fe_status *status)
{ {
...@@ -2158,22 +2223,26 @@ static int stv0367cab_read_status(struct dvb_frontend *fe, ...@@ -2158,22 +2223,26 @@ static int stv0367cab_read_status(struct dvb_frontend *fe,
*status = 0; *status = 0;
if (state->cab_state->state > FE_CAB_NOSIGNAL) /* update cab_state->state from QAM_FSM_STATUS */
*status |= FE_HAS_SIGNAL; state->cab_state->state = stv0367cab_fsm_signaltype(
stv0367cab_fsm_status(state));
if (state->cab_state->state > FE_CAB_NOCARRIER) if (stv0367cab_qamfec_lock(state)) {
*status |= FE_HAS_CARRIER; *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI
| FE_HAS_SYNC | FE_HAS_LOCK;
dprintk("%s: stv0367 has locked\n", __func__);
} else {
if (state->cab_state->state > FE_CAB_NOSIGNAL)
*status |= FE_HAS_SIGNAL;
if (state->cab_state->state >= FE_CAB_DEMODOK) if (state->cab_state->state > FE_CAB_NOCARRIER)
*status |= FE_HAS_VITERBI; *status |= FE_HAS_CARRIER;
if (state->cab_state->state >= FE_CAB_DATAOK) if (state->cab_state->state >= FE_CAB_DEMODOK)
*status |= FE_HAS_SYNC; *status |= FE_HAS_VITERBI;
if (stv0367_readbits(state, (state->cab_state->qamfec_status_reg ? if (state->cab_state->state >= FE_CAB_DATAOK)
state->cab_state->qamfec_status_reg : F367CAB_QAMFEC_LOCK))) { *status |= FE_HAS_SYNC;
*status |= FE_HAS_LOCK;
dprintk("%s: stv0367 has locked\n", __func__);
} }
return 0; return 0;
...@@ -2374,7 +2443,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, ...@@ -2374,7 +2443,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
LockTime = 0; LockTime = 0;
stv0367_writereg(state, R367CAB_CTRL_1, 0x00); stv0367_writereg(state, R367CAB_CTRL_1, 0x00);
do { do {
QAM_Lock = stv0367_readbits(state, F367CAB_FSM_STATUS); QAM_Lock = stv0367cab_fsm_status(state);
if ((LockTime >= (DemodTimeOut - EQLTimeOut)) && if ((LockTime >= (DemodTimeOut - EQLTimeOut)) &&
(QAM_Lock == 0x04)) (QAM_Lock == 0x04))
/* /*
...@@ -2435,10 +2504,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, ...@@ -2435,10 +2504,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
do { do {
usleep_range(5000, 7000); usleep_range(5000, 7000);
LockTime += 5; LockTime += 5;
QAMFEC_Lock = stv0367_readbits(state, QAMFEC_Lock = stv0367cab_qamfec_lock(state);
(state->cab_state->qamfec_status_reg ?
state->cab_state->qamfec_status_reg :
F367CAB_QAMFEC_LOCK));
} while (!QAMFEC_Lock && (LockTime < FECTimeOut)); } while (!QAMFEC_Lock && (LockTime < FECTimeOut));
} else } else
QAMFEC_Lock = 0; QAMFEC_Lock = 0;
...@@ -2474,52 +2540,8 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, ...@@ -2474,52 +2540,8 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
cab_state->locked = 1; cab_state->locked = 1;
/* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/ /* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/
} else { } else
switch (QAM_Lock) { signalType = stv0367cab_fsm_signaltype(QAM_Lock);
case 1:
signalType = FE_CAB_NOAGC;
break;
case 2:
signalType = FE_CAB_NOTIMING;
break;
case 3:
signalType = FE_CAB_TIMINGOK;
break;
case 4:
signalType = FE_CAB_NOCARRIER;
break;
case 5:
signalType = FE_CAB_CARRIEROK;
break;
case 7:
signalType = FE_CAB_NOBLIND;
break;
case 8:
signalType = FE_CAB_BLINDOK;
break;
case 10:
signalType = FE_CAB_NODEMOD;
break;
case 11:
signalType = FE_CAB_DEMODOK;
break;
case 12:
signalType = FE_CAB_DEMODOK;
break;
case 13:
signalType = FE_CAB_NODEMOD;
break;
case 14:
signalType = FE_CAB_NOBLIND;
break;
case 15:
signalType = FE_CAB_NOSIGNAL;
break;
default:
break;
}
}
/* Set the AGC control values to tracking values */ /* Set the AGC control values to tracking values */
stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, TrackAGCAccum); stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, TrackAGCAccum);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment