Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9e23f50a authored by Martin Blumenstingl's avatar Martin Blumenstingl Committed by Mauro Carvalho Chehab
Browse files

[media] drxk: Make the QAM demodulator command parameters configurable



Currently there are two different implementations (in the firmware) for
the QAM demodulator command: one takes 4 and the other takes 2
parameters. The driver shows an error in dmesg When using the
4-parameter command with firmware that implements the 2-parameter
command. Unfortunately this happens every time when chaning the
frequency (on DVB-C).

This patch simply makes configurable, how many command parameters will
be used. All existing drxk_config instances using the "drxk_a3.mc" were
updated because this firmware is the only loadable firmware where the
QAM demodulator command takes 4 parameters. Some firmwares in the ROM
might also use it. The drxk instances in the em28xx-dvb driver were also
updated to silence the warnings.

If no qam_demod_parameter_count is given in the drxk_config struct, then
the correct number of parameters will be auto-detected.

[mchehab@redhat.com: Fix a small CodingStyle issue at one comment]
Signed-off-by: default avatarMartin Blumenstingl <martin.blumenstingl@googlemail.com>
Tested-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 22a09b43
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -578,6 +578,7 @@ static int demod_attach_drxk(struct ddb_input *input)

	memset(&config, 0, sizeof(config));
	config.microcode_name = "drxk_a3.mc";
	config.qam_demod_parameter_count = 4;
	config.adr = 0x29 + (input->nr & 1);

	fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
+10 −1
Original line number Diff line number Diff line
@@ -20,6 +20,14 @@
 *			means that 1=DVBC, 0 = DVBT. Zero means the opposite.
 * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
 * @microcode_name:	Name of the firmware file with the microcode
 * @qam_demod_parameter_count:	The number of parameters used for the command
 *				to set the demodulator parameters. All
 *				firmwares are using the 2-parameter commmand.
 *				An exception is the "drxk_a3.mc" firmware,
 *				which uses the 4-parameter command.
 *				A value of 0 (default) or lower indicates that
 *				the correct number of parameters will be
 *				automatically detected.
 *
 * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
 * UIO-3.
@@ -39,6 +47,7 @@ struct drxk_config {
	int	chunk_size;

	const char	*microcode_name;
	int		 qam_demod_parameter_count;
};

#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
+87 −25
Original line number Diff line number Diff line
@@ -5415,12 +5415,67 @@ static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
#define QAM_LOCKRANGE__M      0x10
#define QAM_LOCKRANGE_NORMAL  0x10

static int QAMDemodulatorCommand(struct drxk_state *state,
				 int numberOfParameters)
{
	int status;
	u16 cmdResult;
	u16 setParamParameters[4] = { 0, 0, 0, 0 };

	setParamParameters[0] = state->m_Constellation;	/* modulation     */
	setParamParameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */

	if (numberOfParameters == 2) {
		u16 setEnvParameters[1] = { 0 };

		if (state->m_OperationMode == OM_QAM_ITU_C)
			setEnvParameters[0] = QAM_TOP_ANNEX_C;
		else
			setEnvParameters[0] = QAM_TOP_ANNEX_A;

		status = scu_command(state,
				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
				     1, setEnvParameters, 1, &cmdResult);
		if (status < 0)
			goto error;

		status = scu_command(state,
				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
				     numberOfParameters, setParamParameters,
				     1, &cmdResult);
	} else if (numberOfParameters == 4) {
		if (state->m_OperationMode == OM_QAM_ITU_C)
			setParamParameters[2] = QAM_TOP_ANNEX_C;
		else
			setParamParameters[2] = QAM_TOP_ANNEX_A;

		setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
		/* Env parameters */
		/* check for LOCKRANGE Extented */
		/* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */

		status = scu_command(state,
				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
				     numberOfParameters, setParamParameters,
				     1, &cmdResult);
	} else {
		printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
			"count %d\n", numberOfParameters);
	}

error:
	if (status < 0)
		printk(KERN_WARNING "drxk: Warning %d on %s\n",
		       status, __func__);
	return status;
}

static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
		  s32 tunerFreqOffset)
{
	int status;
	u16 setParamParameters[4] = { 0, 0, 0, 0 };
	u16 cmdResult;
	int qamDemodParamCount = state->qam_demod_parameter_count;

	dprintk(1, "\n");
	/*
@@ -5472,34 +5527,40 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
	}
	if (status < 0)
		goto error;
	setParamParameters[0] = state->m_Constellation;	/* modulation     */
	setParamParameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
	if (state->m_OperationMode == OM_QAM_ITU_C)
		setParamParameters[2] = QAM_TOP_ANNEX_C;
	else
		setParamParameters[2] = QAM_TOP_ANNEX_A;
	setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
	/* Env parameters */
	/* check for LOCKRANGE Extented */
	/* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */

	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
	/* Use the 4-parameter if it's requested or we're probing for
	 * the correct command. */
	if (state->qam_demod_parameter_count == 4
		|| !state->qam_demod_parameter_count) {
		qamDemodParamCount = 4;
		status = QAMDemodulatorCommand(state, qamDemodParamCount);
	}

	/* Use the 2-parameter command if it was requested or if we're
	 * probing for the correct command and the 4-parameter command
	 * failed. */
	if (state->qam_demod_parameter_count == 2
		|| (!state->qam_demod_parameter_count && status < 0)) {
		qamDemodParamCount = 2;
		status = QAMDemodulatorCommand(state, qamDemodParamCount);
	}

	if (status < 0) {
		/* Fall-back to the simpler call */
		if (state->m_OperationMode == OM_QAM_ITU_C)
			setParamParameters[0] = QAM_TOP_ANNEX_C;
		else
			setParamParameters[0] = QAM_TOP_ANNEX_A;
		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
		if (status < 0)
		dprintk(1, "Could not set demodulator parameters. Make "
			"sure qam_demod_parameter_count (%d) is correct for "
			"your firmware (%s).\n",
			state->qam_demod_parameter_count,
			state->microcode_name);
		goto error;
	} else if (!state->qam_demod_parameter_count) {
		dprintk(1, "Auto-probing the correct QAM demodulator command "
			"parameters was successful - using %d parameters.\n",
			qamDemodParamCount);

		setParamParameters[0] = state->m_Constellation; /* modulation     */
		setParamParameters[1] = DRXK_QAM_I12_J17;       /* interleave mode   */
		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
		/* One of our commands was successful. We don't need to
		/* auto-probe anymore, now that we got the correct command. */
		state->qam_demod_parameter_count = qamDemodParamCount;
	}
	if (status < 0)
		goto error;

	/*
	 * STEP 3: enable the system in a mode where the ADC provides valid
@@ -6502,6 +6563,7 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
	state->demod_address = adr;
	state->single_master = config->single_master;
	state->microcode_name = config->microcode_name;
	state->qam_demod_parameter_count = config->qam_demod_parameter_count;
	state->no_i2c_bridge = config->no_i2c_bridge;
	state->antenna_gpio = config->antenna_gpio;
	state->antenna_dvbt = config->antenna_dvbt;
+1 −0
Original line number Diff line number Diff line
@@ -353,6 +353,7 @@ struct drxk_state {
	const char *microcode_name;
	struct completion fw_wait_load;
	const struct firmware *fw;
	int qam_demod_parameter_count;
};

#define NEVER_LOCK 0
+1 −0
Original line number Diff line number Diff line
@@ -217,6 +217,7 @@ static int demod_attach_drxk(struct ngene_channel *chan,

	memset(&config, 0, sizeof(config));
	config.microcode_name = "drxk_a3.mc";
	config.qam_demod_parameter_count = 4;
	config.adr = 0x29 + (chan->number ^ 2);

	chan->fe = dvb_attach(drxk_attach, &config, i2c);
Loading