Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32e4c3a5 authored by Oliver Endriss's avatar Oliver Endriss Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (4323): [budget/budget-av/budget-ci/budget-patch drivers] fixed DMA start/stop code



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: default avatarOliver Endriss <o.endriss@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 3117beec
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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;
}

+2 −0
Original line number Diff line number Diff line
@@ -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;
}

+44 −13
Original line number Diff line number Diff line
@@ -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,6 +299,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)

	spin_lock(&budget->feedlock);
	feed->pusi_seen = 0; /* have a clean section start */
	if (budget->feeding++ == 0)
		status = start_ts_capture(budget);
	spin_unlock(&budget->feedlock);
	return status;
@@ -285,11 +309,12 @@ 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);
	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);
+2 −0
Original line number Diff line number Diff line
@@ -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;
}

+2 −0
Original line number Diff line number Diff line
@@ -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;
}

Loading