aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew de Quincey <adq_dvb@lidskialf.net>2006-03-30 13:53:35 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-04-02 03:56:02 -0400
commit86f40cc3c994822ffeb226753526d87be21bd79a (patch)
treeaeb2c3cc3989363a234298e1e2b80973f53657b5
parent5e85bd057f0cb29881e3d55d29f48bb55bd2f450 (diff)
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: Andrew de Quincey <adq_dvb@lidskialf.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c18
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h2
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c12
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c13
4 files changed, 27 insertions, 18 deletions
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 {
105 fe_status_t status; 105 fe_status_t status;
106 unsigned long tune_mode_flags; 106 unsigned long tune_mode_flags;
107 unsigned int delay; 107 unsigned int delay;
108 unsigned int reinitialise;
108 109
109 /* swzigzag values */ 110 /* swzigzag values */
110 unsigned int state; 111 unsigned int state;
@@ -121,6 +122,7 @@ struct dvb_frontend_private {
121 unsigned int check_wrapped; 122 unsigned int check_wrapped;
122}; 123};
123 124
125static void dvb_frontend_wakeup(struct dvb_frontend *fe);
124 126
125static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) 127static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
126{ 128{
@@ -213,6 +215,15 @@ static void dvb_frontend_init(struct dvb_frontend *fe)
213 fe->ops->init(fe); 215 fe->ops->init(fe);
214} 216}
215 217
218void dvb_frontend_reinitialise(struct dvb_frontend *fe)
219{
220 struct dvb_frontend_private *fepriv = fe->frontend_priv;
221
222 fepriv->reinitialise = 1;
223 dvb_frontend_wakeup(fe);
224}
225EXPORT_SYMBOL(dvb_frontend_reinitialise);
226
216static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) 227static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
217{ 228{
218 int q2; 229 int q2;
@@ -505,8 +516,8 @@ static int dvb_frontend_thread(void *data)
505 fepriv->quality = 0; 516 fepriv->quality = 0;
506 fepriv->delay = 3*HZ; 517 fepriv->delay = 3*HZ;
507 fepriv->status = 0; 518 fepriv->status = 0;
508 dvb_frontend_init(fe);
509 fepriv->wakeup = 0; 519 fepriv->wakeup = 0;
520 fepriv->reinitialise = 1;
510 521
511 while (1) { 522 while (1) {
512 up(&fepriv->sem); /* is locked when we enter the thread... */ 523 up(&fepriv->sem); /* is locked when we enter the thread... */
@@ -524,6 +535,11 @@ static int dvb_frontend_thread(void *data)
524 if (down_interruptible(&fepriv->sem)) 535 if (down_interruptible(&fepriv->sem))
525 break; 536 break;
526 537
538 if (fepriv->reinitialise) {
539 dvb_frontend_init(fe);
540 fepriv->reinitialise = 0;
541 }
542
527 /* do an iteration of the tuning loop */ 543 /* do an iteration of the tuning loop */
528 if (fe->ops->tune) { 544 if (fe->ops->tune) {
529 /* have we been asked to retune? */ 545 /* 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,
112 112
113extern int dvb_unregister_frontend(struct dvb_frontend* fe); 113extern int dvb_unregister_frontend(struct dvb_frontend* fe);
114 114
115extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
116
115extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); 117extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
116extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime); 118extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
117 119
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 {
52 struct dvb_frontend frontend; 52 struct dvb_frontend frontend;
53 53
54 /* private demod data */ 54 /* private demod data */
55 u8 initialised;
56 enum tda1004x_demod demod_type; 55 enum tda1004x_demod demod_type;
57}; 56};
58 57
@@ -594,9 +593,6 @@ static int tda10045_init(struct dvb_frontend* fe)
594 593
595 dprintk("%s\n", __FUNCTION__); 594 dprintk("%s\n", __FUNCTION__);
596 595
597 if (state->initialised)
598 return 0;
599
600 if (tda10045_fwupload(fe)) { 596 if (tda10045_fwupload(fe)) {
601 printk("tda1004x: firmware upload failed\n"); 597 printk("tda1004x: firmware upload failed\n");
602 return -EIO; 598 return -EIO;
@@ -626,7 +622,6 @@ static int tda10045_init(struct dvb_frontend* fe)
626 622
627 tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk); 623 tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
628 624
629 state->initialised = 1;
630 return 0; 625 return 0;
631} 626}
632 627
@@ -635,9 +630,6 @@ static int tda10046_init(struct dvb_frontend* fe)
635 struct tda1004x_state* state = fe->demodulator_priv; 630 struct tda1004x_state* state = fe->demodulator_priv;
636 dprintk("%s\n", __FUNCTION__); 631 dprintk("%s\n", __FUNCTION__);
637 632
638 if (state->initialised)
639 return 0;
640
641 if (tda10046_fwupload(fe)) { 633 if (tda10046_fwupload(fe)) {
642 printk("tda1004x: firmware upload failed\n"); 634 printk("tda1004x: firmware upload failed\n");
643 return -EIO; 635 return -EIO;
@@ -697,7 +689,6 @@ static int tda10046_init(struct dvb_frontend* fe)
697 // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes 689 // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes
698 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); 690 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
699 691
700 state->initialised = 1;
701 return 0; 692 return 0;
702} 693}
703 694
@@ -1207,7 +1198,6 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1207 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1198 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1208 break; 1199 break;
1209 } 1200 }
1210 state->initialised = 0;
1211 1201
1212 return 0; 1202 return 0;
1213} 1203}
@@ -1271,7 +1261,6 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1271 state->config = config; 1261 state->config = config;
1272 state->i2c = i2c; 1262 state->i2c = i2c;
1273 memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); 1263 memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
1274 state->initialised = 0;
1275 state->demod_type = TDA1004X_DEMOD_TDA10045; 1264 state->demod_type = TDA1004X_DEMOD_TDA10045;
1276 1265
1277 /* check if the demod is there */ 1266 /* check if the demod is there */
@@ -1330,7 +1319,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1330 state->config = config; 1319 state->config = config;
1331 state->i2c = i2c; 1320 state->i2c = i2c;
1332 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); 1321 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1333 state->initialised = 0;
1334 state->demod_type = TDA1004X_DEMOD_TDA10046; 1322 state->demod_type = TDA1004X_DEMOD_TDA10046;
1335 1323
1336 /* check if the demod is there */ 1324 /* 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 {
60 struct dvb_ca_en50221 ca; 60 struct dvb_ca_en50221 ca;
61}; 61};
62 62
63/* GPIO CI Connections: 63/* GPIO Connections:
64 * 0 - Vcc/Reset (Reset is controlled by capacitor) 64 * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
65 * 1 - Attribute Memory 65 * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
66 * 2 - Card Enable (Active Low) 66 * 2 - CI Card Enable (Active Low)
67 * 3 - Card Detect 67 * 3 - CI Card Detect
68 */ 68 */
69 69
70/**************************************************************************** 70/****************************************************************************
@@ -214,6 +214,9 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
214 while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) 214 while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
215 msleep(100); 215 msleep(100);
216 216
217 /* reinitialise the frontend */
218 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
219
217 if (timeout <= 0) 220 if (timeout <= 0)
218 { 221 {
219 printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); 222 printk(KERN_ERR "budget-av: cam reset failed (timeout).\n");