diff options
author | Martin Blumenstingl <martin.blumenstingl@googlemail.com> | 2012-07-04 16:36:55 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-07-06 13:54:43 -0400 |
commit | 9e23f50a762c236049b4965a42d86d55fcdbbfb3 (patch) | |
tree | 1e98cb690824382058e222e9fed4261f3552549d | |
parent | 22a09b439af25fefbe0ebd1c6c2a0d81e923f2f5 (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.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/drxk.h | 11 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/drxk_hard.c | 112 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/drxk_hard.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-cards.c | 1 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 4 |
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 | ||
5418 | static 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 | |||
5466 | error: | ||
5467 | if (status < 0) | ||
5468 | printk(KERN_WARNING "drxk: Warning %d on %s\n", | ||
5469 | status, __func__); | ||
5470 | return status; | ||
5471 | } | ||
5472 | |||
5418 | static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, | 5473 | static 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 | ||
320 | static struct drxk_config hauppauge_930c_drxk = { | 321 | static 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 | ||
328 | struct drxk_config terratec_htc_stick_drxk = { | 330 | struct 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 */ |