diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 2c3ea8f95dcd..4f8f257e6795 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -105,6 +105,7 @@ struct dvb_frontend_private { fe_status_t status; unsigned long tune_mode_flags; unsigned int delay; + unsigned int reinitialise; /* swzigzag values */ unsigned int state; @@ -121,6 +122,7 @@ struct dvb_frontend_private { unsigned int check_wrapped; }; +static void dvb_frontend_wakeup(struct dvb_frontend *fe); static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) { @@ -213,6 +215,15 @@ static void dvb_frontend_init(struct dvb_frontend *fe) fe->ops->init(fe); } +void dvb_frontend_reinitialise(struct dvb_frontend *fe) +{ + struct dvb_frontend_private *fepriv = fe->frontend_priv; + + fepriv->reinitialise = 1; + dvb_frontend_wakeup(fe); +} +EXPORT_SYMBOL(dvb_frontend_reinitialise); + static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) { int q2; @@ -505,8 +516,8 @@ static int dvb_frontend_thread(void *data) fepriv->quality = 0; fepriv->delay = 3*HZ; fepriv->status = 0; - dvb_frontend_init(fe); fepriv->wakeup = 0; + fepriv->reinitialise = 1; while (1) { up(&fepriv->sem); /* is locked when we enter the thread... */ @@ -524,6 +535,11 @@ static int dvb_frontend_thread(void *data) if (down_interruptible(&fepriv->sem)) break; + if (fepriv->reinitialise) { + dvb_frontend_init(fe); + fepriv->reinitialise = 0; + } + /* do an iteration of the tuning loop */ if (fe->ops->tune) { /* have we been asked to retune? */ diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index d5aee5ad67a0..5926a3b745c9 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -112,6 +112,8 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb, extern int dvb_unregister_frontend(struct dvb_frontend* fe); +extern void dvb_frontend_reinitialise(struct dvb_frontend *fe); + extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime); diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 8e8df7b4ca0e..b83dafa4e12c 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -52,7 +52,6 @@ struct tda1004x_state { struct dvb_frontend frontend; /* private demod data */ - u8 initialised; enum tda1004x_demod demod_type; }; @@ -594,9 +593,6 @@ static int tda10045_init(struct dvb_frontend* fe) dprintk("%s\n", __FUNCTION__); - if (state->initialised) - return 0; - if (tda10045_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); return -EIO; @@ -626,7 +622,6 @@ static int tda10045_init(struct dvb_frontend* fe) tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk); - state->initialised = 1; return 0; } @@ -635,9 +630,6 @@ static int tda10046_init(struct dvb_frontend* fe) struct tda1004x_state* state = fe->demodulator_priv; dprintk("%s\n", __FUNCTION__); - if (state->initialised) - return 0; - if (tda10046_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); return -EIO; @@ -697,7 +689,6 @@ static int tda10046_init(struct dvb_frontend* fe) // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); - state->initialised = 1; return 0; } @@ -1207,7 +1198,6 @@ static int tda1004x_sleep(struct dvb_frontend* fe) tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); break; } - state->initialised = 0; return 0; } @@ -1271,7 +1261,6 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); - state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ @@ -1330,7 +1319,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); - state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 9dd4745f5312..8efe3ce5f66c 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -60,11 +60,11 @@ struct budget_av { struct dvb_ca_en50221 ca; }; -/* GPIO CI Connections: - * 0 - Vcc/Reset (Reset is controlled by capacitor) - * 1 - Attribute Memory - * 2 - Card Enable (Active Low) - * 3 - Card Detect +/* GPIO Connections: + * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! + * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory + * 2 - CI Card Enable (Active Low) + * 3 - CI Card Detect */ /**************************************************************************** @@ -214,6 +214,9 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) msleep(100); + /* reinitialise the frontend */ + dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); + if (timeout <= 0) { printk(KERN_ERR "budget-av: cam reset failed (timeout).\n");