in dvb-frontends/drxk_hard.c [3718:4044]
static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
s32 tuner_freq_offset)
{
u16 cmd_result = 0;
u16 transmission_params = 0;
u32 iqm_rc_rate_ofs = 0;
u32 bandwidth = 0;
u16 param1;
int status;
dprintk(1, "IF =%d, TFO = %d\n",
intermediate_freqk_hz, tuner_freq_offset);
status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
| SCU_RAM_COMMAND_CMD_DEMOD_STOP,
0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
/* Halt SCU to enable safe non-atomic accesses */
status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
if (status < 0)
goto error;
/* Stop processors */
status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
if (status < 0)
goto error;
status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
if (status < 0)
goto error;
/* Mandatory fix, always stop CP, required to set spl offset back to
hardware default (is set to 0 by ucode during pilot detection */
status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
if (status < 0)
goto error;
/*== Write channel settings to device ================================*/
/* mode */
switch (state->props.transmission_mode) {
case TRANSMISSION_MODE_AUTO:
case TRANSMISSION_MODE_8K:
default:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
break;
case TRANSMISSION_MODE_2K:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
break;
}
/* guard */
switch (state->props.guard_interval) {
default:
case GUARD_INTERVAL_AUTO: /* try first guess DRX_GUARD_1DIV4 */
case GUARD_INTERVAL_1_4:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
break;
case GUARD_INTERVAL_1_32:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
break;
case GUARD_INTERVAL_1_16:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
break;
case GUARD_INTERVAL_1_8:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
break;
}
/* hierarchy */
switch (state->props.hierarchy) {
case HIERARCHY_AUTO:
case HIERARCHY_NONE:
default: /* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
case HIERARCHY_1:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
break;
case HIERARCHY_2:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
break;
case HIERARCHY_4:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
break;
}
/* modulation */
switch (state->props.modulation) {
case QAM_AUTO:
default: /* try first guess DRX_CONSTELLATION_QAM64 */
case QAM_64:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
break;
case QPSK:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
break;
case QAM_16:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
break;
}
#if 0
/* No hierarchical channels support in BDA */
/* Priority (only for hierarchical channels) */
switch (channel->priority) {
case DRX_PRIORITY_LOW:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
OFDM_EC_SB_PRIOR_LO);
break;
case DRX_PRIORITY_HIGH:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
OFDM_EC_SB_PRIOR_HI));
break;
case DRX_PRIORITY_UNKNOWN:
default:
status = -EINVAL;
goto error;
}
#else
/* Set Priority high */
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
if (status < 0)
goto error;
#endif
/* coderate */
switch (state->props.code_rate_HP) {
case FEC_AUTO:
default: /* try first guess DRX_CODERATE_2DIV3 */
case FEC_2_3:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
break;
case FEC_1_2:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
break;
case FEC_3_4:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
break;
case FEC_5_6:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
break;
case FEC_7_8:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
break;
}
/*
* SAW filter selection: normally not necessary, but if wanted
* the application can select a SAW filter via the driver by
* using UIOs
*/
/* First determine real bandwidth (Hz) */
/* Also set delay for impulse noise cruncher */
/*
* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
* changed by SC for fix for some 8K,1/8 guard but is restored by
* InitEC and ResetEC functions
*/
switch (state->props.bandwidth_hz) {
case 0:
state->props.bandwidth_hz = 8000000;
fallthrough;
case 8000000:
bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3052);
if (status < 0)
goto error;
/* cochannel protection for PAL 8 MHz */
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
7);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
7);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
7);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
1);
if (status < 0)
goto error;
break;
case 7000000:
bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
3491);
if (status < 0)
goto error;
/* cochannel protection for PAL 7 MHz */
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
8);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
8);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
4);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
1);
if (status < 0)
goto error;
break;
case 6000000:
bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
4073);
if (status < 0)
goto error;
/* cochannel protection for NTSC 6 MHz */
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
19);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
19);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
14);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
1);
if (status < 0)
goto error;
break;
default:
status = -EINVAL;
goto error;
}
if (iqm_rc_rate_ofs == 0) {
/* Now compute IQM_RC_RATE_OFS
(((SysFreq/BandWidth)/2)/2) -1) * 2^23)
=>
((SysFreq / BandWidth) * (2^21)) - (2^23)
*/
/* (SysFreq / BandWidth) * (2^28) */
/*
* assert (MAX(sysClk)/MIN(bandwidth) < 16)
* => assert(MAX(sysClk) < 16*MIN(bandwidth))
* => assert(109714272 > 48000000) = true
* so Frac 28 can be used
*/
iqm_rc_rate_ofs = Frac28a((u32)
((state->m_sys_clock_freq *
1000) / 3), bandwidth);
/* (SysFreq / BandWidth) * (2^21), rounding before truncating */
if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
iqm_rc_rate_ofs += 0x80L;
iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
/* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
}
iqm_rc_rate_ofs &=
((((u32) IQM_RC_RATE_OFS_HI__M) <<
IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
if (status < 0)
goto error;
/* Bandwidth setting done */
#if 0
status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
if (status < 0)
goto error;
#endif
status = set_frequency_shifter(state, intermediate_freqk_hz,
tuner_freq_offset, true);
if (status < 0)
goto error;
/*== start SC, write channel settings to SC ==========================*/
/* Activate SCU to enable SCU commands */
status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
if (status < 0)
goto error;
/* Enable SC after setting all other parameters */
status = write16(state, OFDM_SC_COMM_STATE__A, 0);
if (status < 0)
goto error;
status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
if (status < 0)
goto error;
status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
| SCU_RAM_COMMAND_CMD_DEMOD_START,
0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
/* Write SC parameter registers, set all AUTO flags in operation mode */
param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
0, transmission_params, param1, 0, 0, 0);
if (status < 0)
goto error;
if (!state->m_drxk_a3_rom_code)
status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
error:
if (status < 0)
pr_err("Error %d on %s\n", status, __func__);
return status;
}