V4L/DVB (4323): [budget/budget-av/budget-ci/budget-patch drivers] fixed DMA start...
authorOliver Endriss <o.endriss@gmx.de>
Wed, 19 Jul 2006 01:55:23 +0000 (22:55 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Sat, 29 Jul 2006 20:22:23 +0000 (17:22 -0300)
Fix bug reported by Andrew de Quincey:
After cold boot the saa7146 DMA did not start if the demuxer was opened
before the frontend has locked to the signal.
DMA transfers will be started now if (and only if)
the frontend is locked and data should be sent to the demuxer.

Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/dvb/ttpci/budget-av.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttpci/budget-core.c
drivers/media/dvb/ttpci/budget-patch.c
drivers/media/dvb/ttpci/budget.c
drivers/media/dvb/ttpci/budget.h

index 5f111d407730611a661c50b00028f356638efe26..2d21fec23b4d9ea4f04694ab1678bbff747a797d 100644 (file)
@@ -1303,6 +1303,9 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
        budget_av->budget.dvb_adapter.priv = budget_av;
        frontend_init(budget_av);
        ciintf_init(budget_av);
+
+       ttpci_budget_init_hooks(&budget_av->budget);
+
        return 0;
 }
 
index 4b966eea3834b52dc07668c7f99721ce907e2a2c..ffbbb3e34be482cf3071e1dabbb7d76882404e0f 100644 (file)
@@ -1101,6 +1101,8 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
        budget_ci->budget.dvb_adapter.priv = budget_ci;
        frontend_init(budget_ci);
 
+       ttpci_budget_init_hooks(&budget_ci->budget);
+
        return 0;
 }
 
index e4cf7775e07f75f21447fa2f051af771180aad63..e15562f81664ea40c0fd36a34136ca08226b6ef1 100644 (file)
@@ -63,9 +63,6 @@ static int stop_ts_capture(struct budget *budget)
 {
        dprintk(2, "budget: %p\n", budget);
 
-       if (--budget->feeding)
-               return budget->feeding;
-
        saa7146_write(budget->dev, MC1, MASK_20);       // DMA3 off
        SAA7146_IER_DISABLE(budget->dev, MASK_10);
        return 0;
@@ -77,8 +74,8 @@ static int start_ts_capture(struct budget *budget)
 
        dprintk(2, "budget: %p\n", budget);
 
-       if (budget->feeding)
-               return ++budget->feeding;
+       if (!budget->feeding || !budget->fe_synced)
+               return 0;
 
        saa7146_write(dev, MC1, MASK_20);       // DMA3 off
 
@@ -139,7 +136,33 @@ static int start_ts_capture(struct budget *budget)
        SAA7146_IER_ENABLE(budget->dev, MASK_10);       /* VPE */
        saa7146_write(dev, MC1, (MASK_04 | MASK_20));   /* DMA3 on */
 
-       return ++budget->feeding;
+       return 0;
+}
+
+static int budget_read_fe_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct budget *budget = (struct budget *) fe->dvb->priv;
+       int synced;
+       int ret;
+
+       if (budget->read_fe_status)
+               ret = budget->read_fe_status(fe, status);
+       else
+               ret = -EINVAL;
+
+       if (!ret) {
+               synced = (*status & FE_HAS_LOCK);
+               if (synced != budget->fe_synced) {
+                       budget->fe_synced = synced;
+                       spin_lock(&budget->feedlock);
+                       if (synced)
+                               start_ts_capture(budget);
+                       else
+                               stop_ts_capture(budget);
+                       spin_unlock(&budget->feedlock);
+               }
+       }
+       return ret;
 }
 
 static void vpeirq(unsigned long data)
@@ -267,7 +290,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)
 {
        struct dvb_demux *demux = feed->demux;
        struct budget *budget = (struct budget *) demux->priv;
-       int status;
+       int status = 0;
 
        dprintk(2, "budget: %p\n", budget);
 
@@ -276,7 +299,8 @@ static int budget_start_feed(struct dvb_demux_feed *feed)
 
        spin_lock(&budget->feedlock);
        feed->pusi_seen = 0; /* have a clean section start */
-       status = start_ts_capture(budget);
+       if (budget->feeding++ == 0)
+               status = start_ts_capture(budget);
        spin_unlock(&budget->feedlock);
        return status;
 }
@@ -285,12 +309,13 @@ static int budget_stop_feed(struct dvb_demux_feed *feed)
 {
        struct dvb_demux *demux = feed->demux;
        struct budget *budget = (struct budget *) demux->priv;
-       int status;
+       int status = 0;
 
        dprintk(2, "budget: %p\n", budget);
 
        spin_lock(&budget->feedlock);
-       status = stop_ts_capture(budget);
+       if (--budget->feeding == 0)
+               status = stop_ts_capture(budget);
        spin_unlock(&budget->feedlock);
        return status;
 }
@@ -470,6 +495,14 @@ err:
        return ret;
 }
 
+void ttpci_budget_init_hooks(struct budget *budget)
+{
+       if (budget->dvb_frontend && !budget->read_fe_status) {
+               budget->read_fe_status = budget->dvb_frontend->ops.read_status;
+               budget->dvb_frontend->ops.read_status = budget_read_fe_status;
+       }
+}
+
 int ttpci_budget_deinit(struct budget *budget)
 {
        struct saa7146_dev *dev = budget->dev;
@@ -508,11 +541,8 @@ void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port)
        spin_lock(&budget->feedlock);
        budget->video_port = video_port;
        if (budget->feeding) {
-               int oldfeeding = budget->feeding;
-               budget->feeding = 1;
                stop_ts_capture(budget);
                start_ts_capture(budget);
-               budget->feeding = oldfeeding;
        }
        spin_unlock(&budget->feedlock);
 }
@@ -520,6 +550,7 @@ void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port)
 EXPORT_SYMBOL_GPL(ttpci_budget_debiread);
 EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite);
 EXPORT_SYMBOL_GPL(ttpci_budget_init);
+EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks);
 EXPORT_SYMBOL_GPL(ttpci_budget_deinit);
 EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler);
 EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port);
index ee60ce90a4005f562d62ed85f6b8a1b155e68a2f..57227441891e54bea5d0236417042e6f12ede756 100644 (file)
@@ -617,6 +617,8 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte
        budget->dvb_adapter.priv = budget;
        frontend_init(budget);
 
+       ttpci_budget_init_hooks(budget);
+
        return 0;
 }
 
index 1b4d884a9709a43499c456ccffed00d8d12efb6f..863dffb4ed8e5058b42fb31be828297945adc1f8 100644 (file)
@@ -471,6 +471,8 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_
        budget->dvb_adapter.priv = budget;
        frontend_init(budget);
 
+       ttpci_budget_init_hooks(budget);
+
        return 0;
 }
 
index ecea3a13030e6c1016fc03cdf615086ad79f6cbc..e8a5c79178e1e229a331a07225ba521aca9c4434 100644 (file)
@@ -52,9 +52,6 @@ struct budget {
        struct dmx_frontend hw_frontend;
        struct dmx_frontend mem_frontend;
 
-       int fe_synced;
-       struct mutex pid_mutex;
-
        int ci_present;
        int video_port;
 
@@ -74,6 +71,9 @@ struct budget {
 
        struct dvb_adapter dvb_adapter;
        struct dvb_frontend *dvb_frontend;
+       int (*read_fe_status)(struct dvb_frontend *fe, fe_status_t *status);
+       int fe_synced;
+
        void *priv;
 };
 
@@ -106,6 +106,7 @@ static struct saa7146_pci_extension_data x_var = { \
 extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
                             struct saa7146_pci_extension_data *info,
                             struct module *owner);
+extern void ttpci_budget_init_hooks(struct budget *budget);
 extern int ttpci_budget_deinit(struct budget *budget);
 extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr);
 extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port);