static int set_dvbt()

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;
}