diff options
author | Trent Piepho <xyzzy@speakeasy.org> | 2006-04-04 08:30:29 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-25 00:57:44 -0400 |
commit | 87184554722b9d06154d70a48aa63ad744ef3fa9 (patch) | |
tree | 53bfab40c8e6f32175c6d773fb1d2e7e85a867bd /drivers/media/dvb/frontends/or51132.c | |
parent | 005b541f884975544594ceb8f2ff81b623500745 (diff) |
V4L/DVB (3723): Avoid unnecessary firmware re-loads in or51132 frontend
As QAM_64, QAM_256, and QAM_AUTO all use the same firmware, switching
between these modulations doesn't require a firmware re-load. This also
fixes a mishandled error condition, in which the firmware file is loaded
into the kernel, the clock mode is changed, but then the firmware upload
to the device fails. The modulation change is aborted, but the clock
mode would still be changed.
Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Andrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb/frontends/or51132.c')
-rw-r--r-- | drivers/media/dvb/frontends/or51132.c | 81 |
1 files changed, 49 insertions, 32 deletions
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index a2a19aeb3b58..56d1109b90a2 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
@@ -310,6 +310,25 @@ static int or51132_setmode(struct dvb_frontend* fe) | |||
310 | return 0; | 310 | return 0; |
311 | } | 311 | } |
312 | 312 | ||
313 | /* Some modulations use the same firmware. This classifies modulations | ||
314 | by the firmware they use. */ | ||
315 | #define MOD_FWCLASS_UNKNOWN 0 | ||
316 | #define MOD_FWCLASS_VSB 1 | ||
317 | #define MOD_FWCLASS_QAM 2 | ||
318 | static int modulation_fw_class(fe_modulation_t modulation) | ||
319 | { | ||
320 | switch(modulation) { | ||
321 | case VSB_8: | ||
322 | return MOD_FWCLASS_VSB; | ||
323 | case QAM_AUTO: | ||
324 | case QAM_64: | ||
325 | case QAM_256: | ||
326 | return MOD_FWCLASS_QAM; | ||
327 | default: | ||
328 | return MOD_FWCLASS_UNKNOWN; | ||
329 | } | ||
330 | } | ||
331 | |||
313 | static int or51132_set_parameters(struct dvb_frontend* fe, | 332 | static int or51132_set_parameters(struct dvb_frontend* fe, |
314 | struct dvb_frontend_parameters *param) | 333 | struct dvb_frontend_parameters *param) |
315 | { | 334 | { |
@@ -317,45 +336,40 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
317 | u8 buf[4]; | 336 | u8 buf[4]; |
318 | struct or51132_state* state = fe->demodulator_priv; | 337 | struct or51132_state* state = fe->demodulator_priv; |
319 | const struct firmware *fw; | 338 | const struct firmware *fw; |
320 | 339 | const char *fwname; | |
321 | /* Change only if we are actually changing the modulation */ | 340 | int clock_mode; |
322 | if (state->current_modulation != param->u.vsb.modulation) { | 341 | |
323 | switch(param->u.vsb.modulation) { | 342 | /* Upload new firmware only if we need a different one */ |
324 | case VSB_8: | 343 | if (modulation_fw_class(state->current_modulation) != |
344 | modulation_fw_class(param->u.vsb.modulation)) { | ||
345 | switch(modulation_fw_class(param->u.vsb.modulation)) { | ||
346 | case MOD_FWCLASS_VSB: | ||
325 | dprintk("set_parameters VSB MODE\n"); | 347 | dprintk("set_parameters VSB MODE\n"); |
326 | printk("or51132: Waiting for firmware upload(%s)...\n", | 348 | fwname = OR51132_VSB_FIRMWARE; |
327 | OR51132_VSB_FIRMWARE); | 349 | |
328 | ret = request_firmware(&fw, OR51132_VSB_FIRMWARE, | ||
329 | &state->i2c->dev); | ||
330 | if (ret){ | ||
331 | printk(KERN_WARNING "or51132: No firmware up" | ||
332 | "loaded(timeout or file not found?)\n"); | ||
333 | return ret; | ||
334 | } | ||
335 | /* Set non-punctured clock for VSB */ | 350 | /* Set non-punctured clock for VSB */ |
336 | state->config->set_ts_params(fe, 0); | 351 | clock_mode = 0; |
337 | break; | 352 | break; |
338 | case QAM_AUTO: | 353 | case MOD_FWCLASS_QAM: |
339 | case QAM_64: | ||
340 | case QAM_256: | ||
341 | dprintk("set_parameters QAM MODE\n"); | 354 | dprintk("set_parameters QAM MODE\n"); |
342 | printk("or51132: Waiting for firmware upload(%s)...\n", | 355 | fwname = OR51132_QAM_FIRMWARE; |
343 | OR51132_QAM_FIRMWARE); | 356 | |
344 | ret = request_firmware(&fw, OR51132_QAM_FIRMWARE, | ||
345 | &state->i2c->dev); | ||
346 | if (ret){ | ||
347 | printk(KERN_WARNING "or51132: No firmware up" | ||
348 | "loaded(timeout or file not found?)\n"); | ||
349 | return ret; | ||
350 | } | ||
351 | /* Set punctured clock for QAM */ | 357 | /* Set punctured clock for QAM */ |
352 | state->config->set_ts_params(fe, 1); | 358 | clock_mode = 1; |
353 | break; | 359 | break; |
354 | default: | 360 | default: |
355 | printk("or51132:Modulation type(%d) UNSUPPORTED\n", | 361 | printk("or51132: Modulation type(%d) UNSUPPORTED\n", |
356 | param->u.vsb.modulation); | 362 | param->u.vsb.modulation); |
357 | return -1; | 363 | return -1; |
358 | }; | 364 | } |
365 | printk("or51132: Waiting for firmware upload(%s)...\n", | ||
366 | fwname); | ||
367 | ret = request_firmware(&fw, fwname, &state->i2c->dev); | ||
368 | if (ret) { | ||
369 | printk(KERN_WARNING "or51132: No firmware up" | ||
370 | "loaded(timeout or file not found?)\n"); | ||
371 | return ret; | ||
372 | } | ||
359 | ret = or51132_load_firmware(fe, fw); | 373 | ret = or51132_load_firmware(fe, fw); |
360 | release_firmware(fw); | 374 | release_firmware(fw); |
361 | if (ret) { | 375 | if (ret) { |
@@ -364,7 +378,10 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
364 | return ret; | 378 | return ret; |
365 | } | 379 | } |
366 | printk("or51132: Firmware upload complete.\n"); | 380 | printk("or51132: Firmware upload complete.\n"); |
367 | 381 | state->config->set_ts_params(fe, clock_mode); | |
382 | } | ||
383 | /* Change only if we are actually changing the modulation */ | ||
384 | if (state->current_modulation != param->u.vsb.modulation) { | ||
368 | state->current_modulation = param->u.vsb.modulation; | 385 | state->current_modulation = param->u.vsb.modulation; |
369 | or51132_setmode(fe); | 386 | or51132_setmode(fe); |
370 | } | 387 | } |
@@ -373,7 +390,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
373 | param->frequency, 0); | 390 | param->frequency, 0); |
374 | dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " | 391 | dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " |
375 | "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); | 392 | "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); |
376 | if (i2c_writebytes(state, state->config->pll_address ,buf, 4)) | 393 | if (i2c_writebytes(state, state->config->pll_address, buf, 4)) |
377 | printk(KERN_WARNING "or51132: set_parameters error " | 394 | printk(KERN_WARNING "or51132: set_parameters error " |
378 | "writing to tuner\n"); | 395 | "writing to tuner\n"); |
379 | 396 | ||