Commit 86f40cc3 authored by Andrew de Quincey's avatar Andrew de Quincey Committed by Mauro Carvalho Chehab

V4L/DVB (3673): Fix budget-av CAM reset

Unfortunately on the budget-av board, the CAM reset line is tied to the
frontend reset line, so resetting the CAM also zaps the frontend. This
breaks the tda1004x at least, and causes it to fail to tune until the
budget-av module is reloaded. This patch adds an exported function to dvb_frontend
that allows a card to forcibly reinitialise a frontend. The budget-av now
does this on CAM reset, which corrects this problem.
since they do not tie the CAM reset line to the frontend reset line.
Signed-off-by: default avatarAndrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 5e85bd05
...@@ -105,6 +105,7 @@ struct dvb_frontend_private { ...@@ -105,6 +105,7 @@ struct dvb_frontend_private {
fe_status_t status; fe_status_t status;
unsigned long tune_mode_flags; unsigned long tune_mode_flags;
unsigned int delay; unsigned int delay;
unsigned int reinitialise;
/* swzigzag values */ /* swzigzag values */
unsigned int state; unsigned int state;
...@@ -121,6 +122,7 @@ struct dvb_frontend_private { ...@@ -121,6 +122,7 @@ struct dvb_frontend_private {
unsigned int check_wrapped; 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) 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) ...@@ -213,6 +215,15 @@ static void dvb_frontend_init(struct dvb_frontend *fe)
fe->ops->init(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) static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
{ {
int q2; int q2;
...@@ -505,8 +516,8 @@ static int dvb_frontend_thread(void *data) ...@@ -505,8 +516,8 @@ static int dvb_frontend_thread(void *data)
fepriv->quality = 0; fepriv->quality = 0;
fepriv->delay = 3*HZ; fepriv->delay = 3*HZ;
fepriv->status = 0; fepriv->status = 0;
dvb_frontend_init(fe);
fepriv->wakeup = 0; fepriv->wakeup = 0;
fepriv->reinitialise = 1;
while (1) { while (1) {
up(&fepriv->sem); /* is locked when we enter the thread... */ up(&fepriv->sem); /* is locked when we enter the thread... */
...@@ -524,6 +535,11 @@ static int dvb_frontend_thread(void *data) ...@@ -524,6 +535,11 @@ static int dvb_frontend_thread(void *data)
if (down_interruptible(&fepriv->sem)) if (down_interruptible(&fepriv->sem))
break; break;
if (fepriv->reinitialise) {
dvb_frontend_init(fe);
fepriv->reinitialise = 0;
}
/* do an iteration of the tuning loop */ /* do an iteration of the tuning loop */
if (fe->ops->tune) { if (fe->ops->tune) {
/* have we been asked to retune? */ /* have we been asked to retune? */
......
...@@ -112,6 +112,8 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb, ...@@ -112,6 +112,8 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
extern int dvb_unregister_frontend(struct dvb_frontend* fe); 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 void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime); extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
......
...@@ -52,7 +52,6 @@ struct tda1004x_state { ...@@ -52,7 +52,6 @@ struct tda1004x_state {
struct dvb_frontend frontend; struct dvb_frontend frontend;
/* private demod data */ /* private demod data */
u8 initialised;
enum tda1004x_demod demod_type; enum tda1004x_demod demod_type;
}; };
...@@ -594,9 +593,6 @@ static int tda10045_init(struct dvb_frontend* fe) ...@@ -594,9 +593,6 @@ static int tda10045_init(struct dvb_frontend* fe)
dprintk("%s\n", __FUNCTION__); dprintk("%s\n", __FUNCTION__);
if (state->initialised)
return 0;
if (tda10045_fwupload(fe)) { if (tda10045_fwupload(fe)) {
printk("tda1004x: firmware upload failed\n"); printk("tda1004x: firmware upload failed\n");
return -EIO; return -EIO;
...@@ -626,7 +622,6 @@ static int tda10045_init(struct dvb_frontend* fe) ...@@ -626,7 +622,6 @@ static int tda10045_init(struct dvb_frontend* fe)
tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk); tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
state->initialised = 1;
return 0; return 0;
} }
...@@ -635,9 +630,6 @@ static int tda10046_init(struct dvb_frontend* fe) ...@@ -635,9 +630,6 @@ static int tda10046_init(struct dvb_frontend* fe)
struct tda1004x_state* state = fe->demodulator_priv; struct tda1004x_state* state = fe->demodulator_priv;
dprintk("%s\n", __FUNCTION__); dprintk("%s\n", __FUNCTION__);
if (state->initialised)
return 0;
if (tda10046_fwupload(fe)) { if (tda10046_fwupload(fe)) {
printk("tda1004x: firmware upload failed\n"); printk("tda1004x: firmware upload failed\n");
return -EIO; return -EIO;
...@@ -697,7 +689,6 @@ static int tda10046_init(struct dvb_frontend* fe) ...@@ -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, 0x50, 0x80, 0x80); // handle out of guard echoes
tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
state->initialised = 1;
return 0; return 0;
} }
...@@ -1207,7 +1198,6 @@ static int tda1004x_sleep(struct dvb_frontend* fe) ...@@ -1207,7 +1198,6 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
break; break;
} }
state->initialised = 0;
return 0; return 0;
} }
...@@ -1271,7 +1261,6 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, ...@@ -1271,7 +1261,6 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
state->config = config; state->config = config;
state->i2c = i2c; state->i2c = i2c;
memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
state->initialised = 0;
state->demod_type = TDA1004X_DEMOD_TDA10045; state->demod_type = TDA1004X_DEMOD_TDA10045;
/* check if the demod is there */ /* check if the demod is there */
...@@ -1330,7 +1319,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, ...@@ -1330,7 +1319,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
state->config = config; state->config = config;
state->i2c = i2c; state->i2c = i2c;
memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
state->initialised = 0;
state->demod_type = TDA1004X_DEMOD_TDA10046; state->demod_type = TDA1004X_DEMOD_TDA10046;
/* check if the demod is there */ /* check if the demod is there */
......
...@@ -60,11 +60,11 @@ struct budget_av { ...@@ -60,11 +60,11 @@ struct budget_av {
struct dvb_ca_en50221 ca; struct dvb_ca_en50221 ca;
}; };
/* GPIO CI Connections: /* GPIO Connections:
* 0 - Vcc/Reset (Reset is controlled by capacitor) * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
* 1 - Attribute Memory * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
* 2 - Card Enable (Active Low) * 2 - CI Card Enable (Active Low)
* 3 - Card Detect * 3 - CI Card Detect
*/ */
/**************************************************************************** /****************************************************************************
...@@ -214,6 +214,9 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) ...@@ -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) while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
msleep(100); msleep(100);
/* reinitialise the frontend */
dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
if (timeout <= 0) if (timeout <= 0)
{ {
printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); printk(KERN_ERR "budget-av: cam reset failed (timeout).\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment