more status API support

This commit is contained in:
Ralph Metzler
2016-03-22 22:18:13 +01:00
committed by mvoelkel
parent cdaf838cb1
commit 1b0e822b07
4 changed files with 604 additions and 22 deletions

View File

@@ -447,6 +447,18 @@ static int CfgDemodAbortTune(struct mxl *state)
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
}
static int reset_fec_counter(struct mxl *state)
{
MXL_HYDRA_DEMOD_ABORT_TUNE_T abortTuneCmd;
u32 demodIndex = (u32) state->demod;
u8 cmdSize = sizeof(u32);
u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN];
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]);
}
static int send_master_cmd(struct dvb_frontend *fe,
struct dvb_diseqc_master_cmd *cmd)
{
@@ -620,8 +632,52 @@ static int read_snr(struct dvb_frontend *fe, u16 *snr)
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];
int stat;
*ber = 0;
mutex_lock(&state->base->status_lock);
HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
stat = read_register_block(state,
(HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET +
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]);
HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
mutex_unlock(&state->base->status_lock);
switch (p->delivery_system) {
case SYS_DSS:
break;
case SYS_DVBS:
p->pre_bit_error.len = 1;
p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
p->pre_bit_error.stat[0].uvalue = reg[5];
p->pre_bit_count.len = 1;
p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
p->pre_bit_count.stat[0].uvalue = reg[6] * 188 * 8;
break;
case SYS_DVBS2:
break;
default:
break;
}
pr_info("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",
reg[0], reg[1], reg[2], reg[3]);
//pre_bit_error, pre_bit_count
//post_bit_error, post_bit_count;
//block_error block_count;
//reset_fec_counter(state);
return 0;
}
@@ -654,24 +710,99 @@ static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
static int get_stats(struct dvb_frontend *fe)
{
u16 val;
u32 val32;
read_signal_strength(fe, &val);
read_snr(fe, &val);
read_ber(fe, &val32);
return 0;
}
static fe_code_rate_t conv_fec(MXL_HYDRA_FEC_E fec)
{
enum fe_code_rate fec2fec[11] = {
FEC_NONE, FEC_1_2, FEC_3_5, FEC_2_3,
FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7,
FEC_7_8, FEC_8_9, FEC_9_10
};
if (fec > MXL_HYDRA_FEC_9_10)
return FEC_NONE;
return fec2fec[fec];
}
static int get_frontend(struct dvb_frontend *fe)
{
//struct mxl *state = fe->demodulator_priv;
struct mxl *state = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
u32 regData[MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE];
u32 freq;
int stat;
mutex_lock(&state->base->status_lock);
HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
stat = read_register_block(state,
(HYDRA_DMD_STANDARD_ADDR_OFFSET +
HYDRA_DMD_STATUS_OFFSET(state->demod)),
(MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE * 4), // 25 * 4 bytes
(u8 *) &regData[0]);
// read demod channel parameters
stat = read_register_block(state,
(HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR +
HYDRA_DMD_STATUS_OFFSET(state->demod)),
(4), // 4 bytes
(u8 *) &freq);
HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
mutex_unlock(&state->base->status_lock);
pr_info("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];
p->frequency = freq;
//p->delivery_system = (MXL_HYDRA_BCAST_STD_E )regData[DMD_STANDARD_ADDR];
//p->inversion = (MXL_HYDRA_SPECTRUM_E )regData[DMD_SPECTRUM_INVERSION_ADDR];
//freqSearchRangeKHz = (regData[DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR]);
p->fec_inner = conv_fec(regData[DMD_FEC_CODE_RATE_ADDR]);
switch (p->delivery_system) {
case SYS_DSS:
break;
case SYS_DVBS:
break;
case SYS_DVBS2:
switch ((MXL_HYDRA_PILOTS_E ) regData[DMD_DVBS2_PILOT_ON_OFF_ADDR]) {
case MXL_HYDRA_PILOTS_OFF:
p->pilot = PILOT_OFF;
break;
case MXL_HYDRA_PILOTS_ON:
p->pilot = PILOT_ON;
break;
default:
break;
}
case SYS_DVBS:
switch ((MXL_HYDRA_MODULATION_E) regData[DMD_MODULATION_SCHEME_ADDR]) {
case MXL_HYDRA_MOD_QPSK:
p->modulation = QPSK;
break;
case MXL_HYDRA_MOD_8PSK:
p->modulation = PSK_8;
break;
default:
break;
}
switch ((MXL_HYDRA_ROLLOFF_E) regData[DMD_SPECTRUM_ROLL_OFF_ADDR]) {
case MXL_HYDRA_ROLLOFF_0_20:
p->rolloff = ROLLOFF_20;
break;
case MXL_HYDRA_ROLLOFF_0_35:
p->rolloff = ROLLOFF_35;
break;
case MXL_HYDRA_ROLLOFF_0_25:
p->rolloff = ROLLOFF_25;
break;
default:
break;
}
break;
default:
return -EINVAL;