[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: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Tested-by: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
22a09b439a
commit
9e23f50a76
|
@ -578,6 +578,7 @@ static int demod_attach_drxk(struct ddb_input *input)
|
||||||
|
|
||||||
memset(&config, 0, sizeof(config));
|
memset(&config, 0, sizeof(config));
|
||||||
config.microcode_name = "drxk_a3.mc";
|
config.microcode_name = "drxk_a3.mc";
|
||||||
|
config.qam_demod_parameter_count = 4;
|
||||||
config.adr = 0x29 + (input->nr & 1);
|
config.adr = 0x29 + (input->nr & 1);
|
||||||
|
|
||||||
fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
|
fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
|
||||||
|
|
|
@ -20,6 +20,14 @@
|
||||||
* means that 1=DVBC, 0 = DVBT. Zero means the opposite.
|
* means that 1=DVBC, 0 = DVBT. Zero means the opposite.
|
||||||
* @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
|
* @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
|
||||||
* @microcode_name: Name of the firmware file with the microcode
|
* @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
|
* On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
|
||||||
* UIO-3.
|
* UIO-3.
|
||||||
|
@ -39,6 +47,7 @@ struct drxk_config {
|
||||||
int chunk_size;
|
int chunk_size;
|
||||||
|
|
||||||
const char *microcode_name;
|
const char *microcode_name;
|
||||||
|
int qam_demod_parameter_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
|
#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
|
||||||
|
|
|
@ -5415,12 +5415,67 @@ static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
|
||||||
#define QAM_LOCKRANGE__M 0x10
|
#define QAM_LOCKRANGE__M 0x10
|
||||||
#define QAM_LOCKRANGE_NORMAL 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,
|
static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
|
||||||
s32 tunerFreqOffset)
|
s32 tunerFreqOffset)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
u16 setParamParameters[4] = { 0, 0, 0, 0 };
|
|
||||||
u16 cmdResult;
|
u16 cmdResult;
|
||||||
|
int qamDemodParamCount = state->qam_demod_parameter_count;
|
||||||
|
|
||||||
dprintk(1, "\n");
|
dprintk(1, "\n");
|
||||||
/*
|
/*
|
||||||
|
@ -5472,34 +5527,40 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
|
||||||
}
|
}
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
goto error;
|
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
|
||||||
if (status < 0) {
|
* the correct command. */
|
||||||
/* Fall-back to the simpler call */
|
if (state->qam_demod_parameter_count == 4
|
||||||
if (state->m_OperationMode == OM_QAM_ITU_C)
|
|| !state->qam_demod_parameter_count) {
|
||||||
setParamParameters[0] = QAM_TOP_ANNEX_C;
|
qamDemodParamCount = 4;
|
||||||
else
|
status = QAMDemodulatorCommand(state, qamDemodParamCount);
|
||||||
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)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
if (status < 0)
|
|
||||||
|
/* 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) {
|
||||||
|
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;
|
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);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* STEP 3: enable the system in a mode where the ADC provides valid
|
* 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->demod_address = adr;
|
||||||
state->single_master = config->single_master;
|
state->single_master = config->single_master;
|
||||||
state->microcode_name = config->microcode_name;
|
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->no_i2c_bridge = config->no_i2c_bridge;
|
||||||
state->antenna_gpio = config->antenna_gpio;
|
state->antenna_gpio = config->antenna_gpio;
|
||||||
state->antenna_dvbt = config->antenna_dvbt;
|
state->antenna_dvbt = config->antenna_dvbt;
|
||||||
|
|
|
@ -353,6 +353,7 @@ struct drxk_state {
|
||||||
const char *microcode_name;
|
const char *microcode_name;
|
||||||
struct completion fw_wait_load;
|
struct completion fw_wait_load;
|
||||||
const struct firmware *fw;
|
const struct firmware *fw;
|
||||||
|
int qam_demod_parameter_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NEVER_LOCK 0
|
#define NEVER_LOCK 0
|
||||||
|
|
|
@ -217,6 +217,7 @@ static int demod_attach_drxk(struct ngene_channel *chan,
|
||||||
|
|
||||||
memset(&config, 0, sizeof(config));
|
memset(&config, 0, sizeof(config));
|
||||||
config.microcode_name = "drxk_a3.mc";
|
config.microcode_name = "drxk_a3.mc";
|
||||||
|
config.qam_demod_parameter_count = 4;
|
||||||
config.adr = 0x29 + (chan->number ^ 2);
|
config.adr = 0x29 + (chan->number ^ 2);
|
||||||
|
|
||||||
chan->fe = dvb_attach(drxk_attach, &config, i2c);
|
chan->fe = dvb_attach(drxk_attach, &config, i2c);
|
||||||
|
|
|
@ -315,6 +315,7 @@ static struct drxk_config terratec_h5_drxk = {
|
||||||
.single_master = 1,
|
.single_master = 1,
|
||||||
.no_i2c_bridge = 1,
|
.no_i2c_bridge = 1,
|
||||||
.microcode_name = "dvb-usb-terratec-h5-drxk.fw",
|
.microcode_name = "dvb-usb-terratec-h5-drxk.fw",
|
||||||
|
.qam_demod_parameter_count = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct drxk_config hauppauge_930c_drxk = {
|
static struct drxk_config hauppauge_930c_drxk = {
|
||||||
|
@ -323,6 +324,7 @@ static struct drxk_config hauppauge_930c_drxk = {
|
||||||
.no_i2c_bridge = 1,
|
.no_i2c_bridge = 1,
|
||||||
.microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw",
|
.microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw",
|
||||||
.chunk_size = 56,
|
.chunk_size = 56,
|
||||||
|
.qam_demod_parameter_count = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct drxk_config terratec_htc_stick_drxk = {
|
struct drxk_config terratec_htc_stick_drxk = {
|
||||||
|
@ -331,6 +333,7 @@ struct drxk_config terratec_htc_stick_drxk = {
|
||||||
.no_i2c_bridge = 1,
|
.no_i2c_bridge = 1,
|
||||||
.microcode_name = "dvb-usb-terratec-htc-stick-drxk.fw",
|
.microcode_name = "dvb-usb-terratec-htc-stick-drxk.fw",
|
||||||
.chunk_size = 54,
|
.chunk_size = 54,
|
||||||
|
.qam_demod_parameter_count = 2,
|
||||||
/* Required for the antenna_gpio to disable LNA. */
|
/* Required for the antenna_gpio to disable LNA. */
|
||||||
.antenna_dvbt = true,
|
.antenna_dvbt = true,
|
||||||
/* The windows driver uses the same. This will disable LNA. */
|
/* The windows driver uses the same. This will disable LNA. */
|
||||||
|
@ -347,6 +350,7 @@ static struct drxk_config pctv_520e_drxk = {
|
||||||
.adr = 0x29,
|
.adr = 0x29,
|
||||||
.single_master = 1,
|
.single_master = 1,
|
||||||
.microcode_name = "dvb-demod-drxk-pctv.fw",
|
.microcode_name = "dvb-demod-drxk-pctv.fw",
|
||||||
|
.qam_demod_parameter_count = 2,
|
||||||
.chunk_size = 58,
|
.chunk_size = 58,
|
||||||
.antenna_dvbt = true, /* disable LNA */
|
.antenna_dvbt = true, /* disable LNA */
|
||||||
.antenna_gpio = (1 << 2), /* disable LNA */
|
.antenna_gpio = (1 << 2), /* disable LNA */
|
||||||
|
|
Loading…
Reference in New Issue