diff options
Diffstat (limited to 'linux/drivers')
-rw-r--r-- | linux/drivers/media/dvb/ttpci/budget-ci.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index fe97a9627..afe51a149 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -368,14 +368,13 @@ static void ciintf_interrupt (unsigned long data) // ensure we don't get spurious IRQs during initialisation if (!budget_ci->budget.ci_present) return; + // read the CAM status flags = budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1); - - // always set the GPIO mode back to "normal", in case the card is - // yanked at an inopportune moment - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); - if (flags & CICONTROL_CAMDETECT) { + // GPIO should be set to trigger on falling edge if a CAM is present + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); + if (budget_ci->slot_status & SLOTSTATUS_NONE) { // CAM insertion IRQ budget_ci->slot_status = SLOTSTATUS_PRESENT; @@ -391,7 +390,15 @@ static void ciintf_interrupt (unsigned long data) dvb_ca_en50221_frda_irq(&budget_ci->ca, 0); } } else { + + // trigger on rising edge if a CAM is not present - when a CAM is inserted, we + // only want to get the IRQ when it sets READY. If we trigger on the falling edge, + // the CAM might not actually be ready yet. + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); + + // generate a CAM removal IRQ if we haven't already if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) { + // CAM removal IRQ budget_ci->slot_status = SLOTSTATUS_NONE; dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, DVB_CA_EN50221_CAMCHANGE_REMOVED); } @@ -442,7 +449,11 @@ static int ciintf_init(struct budget_ci* budget_ci) // Setup CI slot IRQ tasklet_init (&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); + if (budget_ci->slot_status != SLOTSTATUS_NONE) { + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); + } else { + saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); + } saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03); budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET); |