aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Blumenstingl <martin.blumenstingl@googlemail.com>2012-07-04 16:36:55 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-06 13:54:43 -0400
commit9e23f50a762c236049b4965a42d86d55fcdbbfb3 (patch)
tree1e98cb690824382058e222e9fed4261f3552549d
parent22a09b439af25fefbe0ebd1c6c2a0d81e923f2f5 (diff)
[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>
-rw-r--r--drivers/media/dvb/ddbridge/ddbridge-core.c1
-rw-r--r--drivers/media/dvb/frontends/drxk.h11
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.c112
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.h1
-rw-r--r--drivers/media/dvb/ngene/ngene-cards.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c4
6 files changed, 104 insertions, 26 deletions
diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c
index 131b938e9e81..ebf3f05839d2 100644
--- a/drivers/media/dvb/ddbridge/ddbridge-core.c
+++ b/drivers/media/dvb/ddbridge/ddbridge-core.c
@@ -578,6 +578,7 @@ static int demod_attach_drxk(struct ddb_input *input)
578 578
579 memset(&config, 0, sizeof(config)); 579 memset(&config, 0, sizeof(config));
580 config.microcode_name = "drxk_a3.mc"; 580 config.microcode_name = "drxk_a3.mc";
581 config.qam_demod_parameter_count = 4;
581 config.adr = 0x29 + (input->nr & 1); 582 config.adr = 0x29 + (input->nr & 1);
582 583
583 fe = input->fe = dvb_attach(drxk_attach, &config, i2c); 584 fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h
index 9d64e4fea066..d615d7d055a2 100644
--- a/drivers/media/dvb/frontends/drxk.h
+++ b/drivers/media/dvb/frontends/drxk.h
@@ -20,6 +20,14 @@
20 * means that 1=DVBC, 0 = DVBT. Zero means the opposite. 20 * means that 1=DVBC, 0 = DVBT. Zero means the opposite.
21 * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength. 21 * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
22 * @microcode_name: Name of the firmware file with the microcode 22 * @microcode_name: Name of the firmware file with the microcode
23 * @qam_demod_parameter_count: The number of parameters used for the command
24 * to set the demodulator parameters. All
25 * firmwares are using the 2-parameter commmand.
26 * An exception is the "drxk_a3.mc" firmware,
27 * which uses the 4-parameter command.
28 * A value of 0 (default) or lower indicates that
29 * the correct number of parameters will be
30 * automatically detected.
23 * 31 *
24 * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is 32 * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
25 * UIO-3. 33 * UIO-3.
@@ -38,7 +46,8 @@ struct drxk_config {
38 u8 mpeg_out_clk_strength; 46 u8 mpeg_out_clk_strength;
39 int chunk_size; 47 int chunk_size;
40 48
41 const char *microcode_name; 49 const char *microcode_name;
50 int qam_demod_parameter_count;
42}; 51};
43 52
44#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \ 53#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
index 317530f891c0..f370ec1c9bd3 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -5415,12 +5415,67 @@ static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5415#define QAM_LOCKRANGE__M 0x10 5415#define QAM_LOCKRANGE__M 0x10
5416#define QAM_LOCKRANGE_NORMAL 0x10 5416#define QAM_LOCKRANGE_NORMAL 0x10
5417 5417
5418static int QAMDemodulatorCommand(struct drxk_state *state,
5419 int numberOfParameters)
5420{
5421 int status;
5422 u16 cmdResult;
5423 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5424
5425 setParamParameters[0] = state->m_Constellation; /* modulation */
5426 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5427
5428 if (numberOfParameters == 2) {
5429 u16 setEnvParameters[1] = { 0 };
5430
5431 if (state->m_OperationMode == OM_QAM_ITU_C)
5432 setEnvParameters[0] = QAM_TOP_ANNEX_C;
5433 else
5434 setEnvParameters[0] = QAM_TOP_ANNEX_A;
5435
5436 status = scu_command(state,
5437 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
5438 1, setEnvParameters, 1, &cmdResult);
5439 if (status < 0)
5440 goto error;
5441
5442 status = scu_command(state,
5443 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5444 numberOfParameters, setParamParameters,
5445 1, &cmdResult);
5446 } else if (numberOfParameters == 4) {
5447 if (state->m_OperationMode == OM_QAM_ITU_C)
5448 setParamParameters[2] = QAM_TOP_ANNEX_C;
5449 else
5450 setParamParameters[2] = QAM_TOP_ANNEX_A;
5451
5452 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5453 /* Env parameters */
5454 /* check for LOCKRANGE Extented */
5455 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5456
5457 status = scu_command(state,
5458 SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
5459 numberOfParameters, setParamParameters,
5460 1, &cmdResult);
5461 } else {
5462 printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
5463 "count %d\n", numberOfParameters);
5464 }
5465
5466error:
5467 if (status < 0)
5468 printk(KERN_WARNING "drxk: Warning %d on %s\n",
5469 status, __func__);
5470 return status;
5471}
5472
5418static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, 5473static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5419 s32 tunerFreqOffset) 5474 s32 tunerFreqOffset)
5420{ 5475{
5421 int status; 5476 int status;
5422 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5423 u16 cmdResult; 5477 u16 cmdResult;
5478 int qamDemodParamCount = state->qam_demod_parameter_count;
5424 5479
5425 dprintk(1, "\n"); 5480 dprintk(1, "\n");
5426 /* 5481 /*
@@ -5472,34 +5527,40 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5472 } 5527 }
5473 if (status < 0) 5528 if (status < 0)
5474 goto error; 5529 goto error;
5475 setParamParameters[0] = state->m_Constellation; /* modulation */
5476 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5477 if (state->m_OperationMode == OM_QAM_ITU_C)
5478 setParamParameters[2] = QAM_TOP_ANNEX_C;
5479 else
5480 setParamParameters[2] = QAM_TOP_ANNEX_A;
5481 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5482 /* Env parameters */
5483 /* check for LOCKRANGE Extented */
5484 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5485 5530
5486 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult); 5531 /* Use the 4-parameter if it's requested or we're probing for
5487 if (status < 0) { 5532 * the correct command. */
5488 /* Fall-back to the simpler call */ 5533 if (state->qam_demod_parameter_count == 4
5489 if (state->m_OperationMode == OM_QAM_ITU_C) 5534 || !state->qam_demod_parameter_count) {
5490 setParamParameters[0] = QAM_TOP_ANNEX_C; 5535 qamDemodParamCount = 4;
5491 else 5536 status = QAMDemodulatorCommand(state, qamDemodParamCount);
5492 setParamParameters[0] = QAM_TOP_ANNEX_A; 5537 }
5493 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5494 if (status < 0)
5495 goto error;
5496 5538
5497 setParamParameters[0] = state->m_Constellation; /* modulation */ 5539 /* Use the 2-parameter command if it was requested or if we're
5498 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ 5540 * probing for the correct command and the 4-parameter command
5499 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult); 5541 * failed. */
5542 if (state->qam_demod_parameter_count == 2
5543 || (!state->qam_demod_parameter_count && status < 0)) {
5544 qamDemodParamCount = 2;
5545 status = QAMDemodulatorCommand(state, qamDemodParamCount);
5500 } 5546 }
5501 if (status < 0) 5547
5548 if (status < 0) {
5549 dprintk(1, "Could not set demodulator parameters. Make "
5550 "sure qam_demod_parameter_count (%d) is correct for "
5551 "your firmware (%s).\n",
5552 state->qam_demod_parameter_count,
5553 state->microcode_name);
5502 goto error; 5554 goto error;
5555 } else if (!state->qam_demod_parameter_count) {
5556 dprintk(1, "Auto-probing the correct QAM demodulator command "
5557 "parameters was successful - using %d parameters.\n",
5558 qamDemodParamCount);
5559
5560 /* One of our commands was successful. We don't need to
5561 /* auto-probe anymore, now that we got the correct command. */
5562 state->qam_demod_parameter_count = qamDemodParamCount;
5563 }
5503 5564
5504 /* 5565 /*
5505 * STEP 3: enable the system in a mode where the ADC provides valid 5566 * 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,
6502 state->demod_address = adr; 6563 state->demod_address = adr;
6503 state->single_master = config->single_master; 6564 state->single_master = config->single_master;
6504 state->microcode_name = config->microcode_name; 6565 state->microcode_name = config->microcode_name;
6566 state->qam_demod_parameter_count = config->qam_demod_parameter_count;
6505 state->no_i2c_bridge = config->no_i2c_bridge; 6567 state->no_i2c_bridge = config->no_i2c_bridge;
6506 state->antenna_gpio = config->antenna_gpio; 6568 state->antenna_gpio = config->antenna_gpio;
6507 state->antenna_dvbt = config->antenna_dvbt; 6569 state->antenna_dvbt = config->antenna_dvbt;
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h
index f41779700106..6bb9fc4a7b96 100644
--- a/drivers/media/dvb/frontends/drxk_hard.h
+++ b/drivers/media/dvb/frontends/drxk_hard.h
@@ -353,6 +353,7 @@ struct drxk_state {
353 const char *microcode_name; 353 const char *microcode_name;
354 struct completion fw_wait_load; 354 struct completion fw_wait_load;
355 const struct firmware *fw; 355 const struct firmware *fw;
356 int qam_demod_parameter_count;
356}; 357};
357 358
358#define NEVER_LOCK 0 359#define NEVER_LOCK 0
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
index 7539a5d71029..72ee8de02260 100644
--- a/drivers/media/dvb/ngene/ngene-cards.c
+++ b/drivers/media/dvb/ngene/ngene-cards.c
@@ -217,6 +217,7 @@ static int demod_attach_drxk(struct ngene_channel *chan,
217 217
218 memset(&config, 0, sizeof(config)); 218 memset(&config, 0, sizeof(config));
219 config.microcode_name = "drxk_a3.mc"; 219 config.microcode_name = "drxk_a3.mc";
220 config.qam_demod_parameter_count = 4;
220 config.adr = 0x29 + (chan->number ^ 2); 221 config.adr = 0x29 + (chan->number ^ 2);
221 222
222 chan->fe = dvb_attach(drxk_attach, &config, i2c); 223 chan->fe = dvb_attach(drxk_attach, &config, i2c);
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index f8ffe102d295..a16531fa937a 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -315,6 +315,7 @@ static struct drxk_config terratec_h5_drxk = {
315 .single_master = 1, 315 .single_master = 1,
316 .no_i2c_bridge = 1, 316 .no_i2c_bridge = 1,
317 .microcode_name = "dvb-usb-terratec-h5-drxk.fw", 317 .microcode_name = "dvb-usb-terratec-h5-drxk.fw",
318 .qam_demod_parameter_count = 2,
318}; 319};
319 320
320static struct drxk_config hauppauge_930c_drxk = { 321static struct drxk_config hauppauge_930c_drxk = {
@@ -323,6 +324,7 @@ static struct drxk_config hauppauge_930c_drxk = {
323 .no_i2c_bridge = 1, 324 .no_i2c_bridge = 1,
324 .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", 325 .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw",
325 .chunk_size = 56, 326 .chunk_size = 56,
327 .qam_demod_parameter_count = 2,
326}; 328};
327 329
328struct drxk_config terratec_htc_stick_drxk = { 330struct drxk_config terratec_htc_stick_drxk = {
@@ -331,6 +333,7 @@ struct drxk_config terratec_htc_stick_drxk = {
331 .no_i2c_bridge = 1, 333 .no_i2c_bridge = 1,
332 .microcode_name = "dvb-usb-terratec-htc-stick-drxk.fw", 334 .microcode_name = "dvb-usb-terratec-htc-stick-drxk.fw",
333 .chunk_size = 54, 335 .chunk_size = 54,
336 .qam_demod_parameter_count = 2,
334 /* Required for the antenna_gpio to disable LNA. */ 337 /* Required for the antenna_gpio to disable LNA. */
335 .antenna_dvbt = true, 338 .antenna_dvbt = true,
336 /* The windows driver uses the same. This will disable LNA. */ 339 /* The windows driver uses the same. This will disable LNA. */
@@ -347,6 +350,7 @@ static struct drxk_config pctv_520e_drxk = {
347 .adr = 0x29, 350 .adr = 0x29,
348 .single_master = 1, 351 .single_master = 1,
349 .microcode_name = "dvb-demod-drxk-pctv.fw", 352 .microcode_name = "dvb-demod-drxk-pctv.fw",
353 .qam_demod_parameter_count = 2,
350 .chunk_size = 58, 354 .chunk_size = 58,
351 .antenna_dvbt = true, /* disable LNA */ 355 .antenna_dvbt = true, /* disable LNA */
352 .antenna_gpio = (1 << 2), /* disable LNA */ 356 .antenna_gpio = (1 << 2), /* disable LNA */