summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-ci.c25
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-core.c46
-rw-r--r--linux/drivers/media/dvb/ttpci/budget.h7
3 files changed, 63 insertions, 15 deletions
diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c
index 77d75a78e..1e54b0671 100644
--- a/linux/drivers/media/dvb/ttpci/budget-ci.c
+++ b/linux/drivers/media/dvb/ttpci/budget-ci.c
@@ -329,24 +329,36 @@ static int ciintf_slot_reset(struct dvb_ca_en50221* ca, int slot) {
dvb_delay(1);
budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET);
+ saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
+ ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
return 0;
}
static int ciintf_slot_shutdown(struct dvb_ca_en50221* ca, int slot) {
+ struct budget_ci* budget_ci = (struct budget_ci*) ca->data;
+ struct saa7146_dev *saa = budget_ci->budget.dev;
+
if (slot != 0) return -EINVAL;
- // no implementation necessary
+ saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
+ ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
return 0;
}
static int ciintf_slot_ts_enable(struct dvb_ca_en50221* ca, int slot) {
struct budget_ci* budget_ci = (struct budget_ci*) ca->data;
+ struct saa7146_dev *saa = budget_ci->budget.dev;
int tmp;
if (slot != 0) return -EINVAL;
+
+ saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
+
tmp = budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1);
budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, tmp | CICONTROL_ENABLETS);
+
+ ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
return 0;
}
@@ -423,10 +435,10 @@ static int ciintf_init(struct budget_ci* budget_ci)
budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
budget_ci->ca.data = budget_ci;
if ((result = dvb_ca_en50221_init(budget_ci->budget.dvb_adapter,
- &budget_ci->ca,
- DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
- DVB_CA_EN50221_FLAG_IRQ_FR |
- DVB_CA_EN50221_FLAG_IRQ_DA,
+ &budget_ci->ca,
+ DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
+ DVB_CA_EN50221_FLAG_IRQ_FR |
+ DVB_CA_EN50221_FLAG_IRQ_DA,
1)) != 0) {
printk("budget_ci: CI interface detected, but initialisation failed.\n");
goto error;
@@ -442,9 +454,6 @@ static int ciintf_init(struct budget_ci* budget_ci)
printk("budget_ci: CI interface initialised\n");
budget_ci->budget.ci_present = 1;
- // route TS data out to CI interface
- saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
-
// forge a fake CI IRQ so the CAM state is setup correctly
flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
if (budget_ci->slot_status != SLOTSTATUS_NONE) flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
diff --git a/linux/drivers/media/dvb/ttpci/budget-core.c b/linux/drivers/media/dvb/ttpci/budget-core.c
index de3100d0e..87758931f 100644
--- a/linux/drivers/media/dvb/ttpci/budget-core.c
+++ b/linux/drivers/media/dvb/ttpci/budget-core.c
@@ -90,14 +90,14 @@ static int start_ts_capture (struct budget *budget)
saa7146_write(dev, MC2, (MASK_09 | MASK_25));
saa7146_write(dev, BRS_CTRL, 0x00000000);
} else {
- if (!budget->ci_present) {
- saa7146_write(dev, DD1_INIT, 0x02000600);
- saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
- saa7146_write(dev, BRS_CTRL, 0x60000000);
- } else {
+ if (budget->video_port == BUDGET_VIDEO_PORTA) {
saa7146_write(dev, DD1_INIT, 0x06000200);
saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
saa7146_write(dev, BRS_CTRL, 0x00000000);
+ } else {
+ saa7146_write(dev, DD1_INIT, 0x02000600);
+ saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+ saa7146_write(dev, BRS_CTRL, 0x60000000);
}
}
@@ -164,23 +164,31 @@ 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;
DEB_EE(("budget: %p\n",budget));
if (!demux->dmx.frontend)
return -EINVAL;
- return start_ts_capture (budget);
+ spin_lock(&budget->feedlock);
+ status = start_ts_capture (budget);
+ spin_unlock(&budget->feedlock);
+ return status;
}
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;
DEB_EE(("budget: %p\n",budget));
- return stop_ts_capture (budget);
+ spin_lock(&budget->feedlock);
+ status = stop_ts_capture (budget);
+ spin_unlock(&budget->feedlock);
+ return status;
}
@@ -282,6 +290,12 @@ int ttpci_budget_init (struct budget *budget,
saa7146_write(dev, DD1_INIT, 0x02000000);
saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+ if (bi->type != BUDGET_FS_ACTIVY)
+ budget->video_port = BUDGET_VIDEO_PORTB;
+ else
+ budget->video_port = BUDGET_VIDEO_PORTA;
+ spin_lock_init(&budget->feedlock);
+
/* the Siemens DVB needs this if you want to have the i2c chips
get recognized before the main driver is loaded */
if (bi->type != BUDGET_FS_ACTIVY)
@@ -364,10 +378,28 @@ void ttpci_budget_irq10_handler (struct saa7146_dev* dev, u32 *isr)
tasklet_schedule (&budget->vpe_tasklet);
}
+void ttpci_budget_set_video_port(struct saa7146_dev* dev, int video_port)
+{
+ struct budget *budget = (struct budget*)dev->ext_priv;
+
+ 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);
+}
+
+
EXPORT_SYMBOL_GPL(ttpci_budget_init);
EXPORT_SYMBOL_GPL(ttpci_budget_deinit);
EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler);
+EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port);
EXPORT_SYMBOL_GPL(budget_debug);
MODULE_PARM(budget_debug,"i");
diff --git a/linux/drivers/media/dvb/ttpci/budget.h b/linux/drivers/media/dvb/ttpci/budget.h
index b0d315a0f..a89f2e567 100644
--- a/linux/drivers/media/dvb/ttpci/budget.h
+++ b/linux/drivers/media/dvb/ttpci/budget.h
@@ -47,11 +47,14 @@ struct budget {
struct semaphore pid_mutex;
int ci_present;
+ int video_port;
u8 tsf;
u32 ttbp;
int feeding;
+ spinlock_t feedlock;
+
struct dvb_adapter *dvb_adapter;
void *priv;
};
@@ -77,11 +80,15 @@ static struct saa7146_pci_extension_data x_var = { \
#define BUDGET_PATCH 3
#define BUDGET_FS_ACTIVY 4
+#define BUDGET_VIDEO_PORTA 0
+#define BUDGET_VIDEO_PORTB 1
+
extern int ttpci_budget_init (struct budget *budget,
struct saa7146_dev* dev,
struct saa7146_pci_extension_data *info);
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);
#endif