aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ttpci/budget-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/ttpci/budget-core.c')
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index e4cf7775e07f..e15562f81664 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -63,9 +63,6 @@ static int stop_ts_capture(struct budget *budget)
63{ 63{
64 dprintk(2, "budget: %p\n", budget); 64 dprintk(2, "budget: %p\n", budget);
65 65
66 if (--budget->feeding)
67 return budget->feeding;
68
69 saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off 66 saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off
70 SAA7146_IER_DISABLE(budget->dev, MASK_10); 67 SAA7146_IER_DISABLE(budget->dev, MASK_10);
71 return 0; 68 return 0;
@@ -77,8 +74,8 @@ static int start_ts_capture(struct budget *budget)
77 74
78 dprintk(2, "budget: %p\n", budget); 75 dprintk(2, "budget: %p\n", budget);
79 76
80 if (budget->feeding) 77 if (!budget->feeding || !budget->fe_synced)
81 return ++budget->feeding; 78 return 0;
82 79
83 saa7146_write(dev, MC1, MASK_20); // DMA3 off 80 saa7146_write(dev, MC1, MASK_20); // DMA3 off
84 81
@@ -139,7 +136,33 @@ static int start_ts_capture(struct budget *budget)
139 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ 136 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
140 saa7146_write(dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ 137 saa7146_write(dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
141 138
142 return ++budget->feeding; 139 return 0;
140}
141
142static int budget_read_fe_status(struct dvb_frontend *fe, fe_status_t *status)
143{
144 struct budget *budget = (struct budget *) fe->dvb->priv;
145 int synced;
146 int ret;
147
148 if (budget->read_fe_status)
149 ret = budget->read_fe_status(fe, status);
150 else
151 ret = -EINVAL;
152
153 if (!ret) {
154 synced = (*status & FE_HAS_LOCK);
155 if (synced != budget->fe_synced) {
156 budget->fe_synced = synced;
157 spin_lock(&budget->feedlock);
158 if (synced)
159 start_ts_capture(budget);
160 else
161 stop_ts_capture(budget);
162 spin_unlock(&budget->feedlock);
163 }
164 }
165 return ret;
143} 166}
144 167
145static void vpeirq(unsigned long data) 168static void vpeirq(unsigned long data)
@@ -267,7 +290,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)
267{ 290{
268 struct dvb_demux *demux = feed->demux; 291 struct dvb_demux *demux = feed->demux;
269 struct budget *budget = (struct budget *) demux->priv; 292 struct budget *budget = (struct budget *) demux->priv;
270 int status; 293 int status = 0;
271 294
272 dprintk(2, "budget: %p\n", budget); 295 dprintk(2, "budget: %p\n", budget);
273 296
@@ -276,7 +299,8 @@ static int budget_start_feed(struct dvb_demux_feed *feed)
276 299
277 spin_lock(&budget->feedlock); 300 spin_lock(&budget->feedlock);
278 feed->pusi_seen = 0; /* have a clean section start */ 301 feed->pusi_seen = 0; /* have a clean section start */
279 status = start_ts_capture(budget); 302 if (budget->feeding++ == 0)
303 status = start_ts_capture(budget);
280 spin_unlock(&budget->feedlock); 304 spin_unlock(&budget->feedlock);
281 return status; 305 return status;
282} 306}
@@ -285,12 +309,13 @@ static int budget_stop_feed(struct dvb_demux_feed *feed)
285{ 309{
286 struct dvb_demux *demux = feed->demux; 310 struct dvb_demux *demux = feed->demux;
287 struct budget *budget = (struct budget *) demux->priv; 311 struct budget *budget = (struct budget *) demux->priv;
288 int status; 312 int status = 0;
289 313
290 dprintk(2, "budget: %p\n", budget); 314 dprintk(2, "budget: %p\n", budget);
291 315
292 spin_lock(&budget->feedlock); 316 spin_lock(&budget->feedlock);
293 status = stop_ts_capture(budget); 317 if (--budget->feeding == 0)
318 status = stop_ts_capture(budget);
294 spin_unlock(&budget->feedlock); 319 spin_unlock(&budget->feedlock);
295 return status; 320 return status;
296} 321}
@@ -470,6 +495,14 @@ err:
470 return ret; 495 return ret;
471} 496}
472 497
498void ttpci_budget_init_hooks(struct budget *budget)
499{
500 if (budget->dvb_frontend && !budget->read_fe_status) {
501 budget->read_fe_status = budget->dvb_frontend->ops.read_status;
502 budget->dvb_frontend->ops.read_status = budget_read_fe_status;
503 }
504}
505
473int ttpci_budget_deinit(struct budget *budget) 506int ttpci_budget_deinit(struct budget *budget)
474{ 507{
475 struct saa7146_dev *dev = budget->dev; 508 struct saa7146_dev *dev = budget->dev;
@@ -508,11 +541,8 @@ void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port)
508 spin_lock(&budget->feedlock); 541 spin_lock(&budget->feedlock);
509 budget->video_port = video_port; 542 budget->video_port = video_port;
510 if (budget->feeding) { 543 if (budget->feeding) {
511 int oldfeeding = budget->feeding;
512 budget->feeding = 1;
513 stop_ts_capture(budget); 544 stop_ts_capture(budget);
514 start_ts_capture(budget); 545 start_ts_capture(budget);
515 budget->feeding = oldfeeding;
516 } 546 }
517 spin_unlock(&budget->feedlock); 547 spin_unlock(&budget->feedlock);
518} 548}
@@ -520,6 +550,7 @@ void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port)
520EXPORT_SYMBOL_GPL(ttpci_budget_debiread); 550EXPORT_SYMBOL_GPL(ttpci_budget_debiread);
521EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite); 551EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite);
522EXPORT_SYMBOL_GPL(ttpci_budget_init); 552EXPORT_SYMBOL_GPL(ttpci_budget_init);
553EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks);
523EXPORT_SYMBOL_GPL(ttpci_budget_deinit); 554EXPORT_SYMBOL_GPL(ttpci_budget_deinit);
524EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); 555EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler);
525EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port); 556EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port);