diff options
Diffstat (limited to 'wcfxo.c')
-rwxr-xr-x | wcfxo.c | 47 |
1 files changed, 43 insertions, 4 deletions
@@ -45,6 +45,10 @@ /* Un-comment the following for POTS line support for Japan */ /* #define JAPAN */ +/* Un-comment for lines (eg from and ISDN TA) that remove */ +/* phone power during ringing */ +/* #define ZERO_BATT_RING */ + #define WC_MAX_IFACES 128 #define WC_CNTL 0x00 @@ -70,6 +74,10 @@ #define FLAG_WRITE 1 #define FLAG_READ 2 +#ifdef ZERO_BATT_RING /* Need to debounce Off/On hook too */ +#define JAPAN +#endif + #define RING_DEBOUNCE 64 /* Ringer Debounce (in ms) */ #ifdef JAPAN #define BATT_DEBOUNCE 30 /* Battery debounce (in ms) */ @@ -168,6 +176,8 @@ static int debug = 0; static int monitor = 0; +static int quiet = 0; + static inline void wcfxo_transmitprep(struct wcfxo *wc, unsigned char ints) { volatile int *writechunk; @@ -357,6 +367,9 @@ static void wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs) struct wcfxo *wc = dev_id; unsigned char ints; unsigned char b; +#ifdef ZERO_BATT_RING + static int onhook = 0; +#endif #ifdef DEBUG_RING static int oldb = 0; static int oldcnt = 0; @@ -409,13 +422,24 @@ static void wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs) printk("NO BATTERY!\n"); wc->battery = 0; #ifdef JAPAN - if ((!wc->ohdebounce) && wc->offhook) -#endif + if ((!wc->ohdebounce) && wc->offhook) { zt_hooksig(&wc->chan, ZT_RXSIG_ONHOOK); + if (debug) + printk("Signalled On Hook\n"); +#ifdef ZERO_BATT_RING + onhook++; +#endif + } +#else + zt_hooksig(&wc->chan, ZT_RXSIG_ONHOOK); +#endif wc->battdebounce = BATT_DEBOUNCE; } else if (!wc->battery) wc->battdebounce = BATT_DEBOUNCE; if ((wc->nobatttimer > 1000) && +#ifdef ZERO_BATT_RING + !(wc->readregs[0x05] & 0x04) && +#endif (!wc->span.alarms)) { wc->span.alarms = ZT_ALARM_RED; zt_alarm_notify(&wc->span); @@ -424,7 +448,16 @@ static void wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (!wc->battery && !wc->battdebounce) { if (debug) printk("BATTERY!\n"); +#ifdef ZERO_BATT_RING + if (onhook) { + onhook = 0; + zt_hooksig(&wc->chan, ZT_RXSIG_OFFHOOK); + if (debug) + printk("Signalled Off Hook\n"); + } +#else zt_hooksig(&wc->chan, ZT_RXSIG_OFFHOOK); +#endif wc->battery = 1; wc->nobatttimer = 0; wc->battdebounce = BATT_DEBOUNCE; @@ -595,11 +628,11 @@ static int wcfxo_hardware_init(struct wcfxo *wc) /* Setup DMA Addresses */ outl(wc->writedma, wc->ioaddr + WC_DMAWS); /* Write start */ - outl(wc->writedma + ZT_CHUNKSIZE * 8, wc->ioaddr + WC_DMAWI); /* Middle (interrupt) */ + outl(wc->writedma + ZT_CHUNKSIZE * 8 - 4, wc->ioaddr + WC_DMAWI); /* Middle (interrupt) */ outl(wc->writedma + ZT_CHUNKSIZE * 16 - 4, wc->ioaddr + WC_DMAWE); /* End */ outl(wc->readdma, wc->ioaddr + WC_DMARS); /* Read start */ - outl(wc->readdma + ZT_CHUNKSIZE * 8, wc->ioaddr + WC_DMARI); /* Middle (interrupt) */ + outl(wc->readdma + ZT_CHUNKSIZE * 8 - 4, wc->ioaddr + WC_DMARI); /* Middle (interrupt) */ outl(wc->readdma + ZT_CHUNKSIZE * 16 - 4, wc->ioaddr + WC_DMARE); /* End */ /* Clear interrupts */ @@ -677,6 +710,11 @@ static int wcfxo_init_daa(struct wcfxo *wc) set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1 + (ZT_CHUNKSIZE * HZ) / 800); + /* Go ahead and attenuate transmit signal by 6 db */ + if (quiet) { + printk("wcfxo: Attenuating transmit signal for quiet operation\n"); + wcfxo_setreg(wc, 0xf, 0x10); + } /* Didn't get it right. Register 9 is still garbage */ if (wc->readregs[0x9] != 0x89) return -1; @@ -863,6 +901,7 @@ static void __exit wcfxo_cleanup(void) } MODULE_PARM(debug, "i"); +MODULE_PARM(quiet, "i"); MODULE_PARM(monitor, "i"); MODULE_DESCRIPTION("Wildcard X100P Zaptel Driver"); MODULE_AUTHOR("Mark Spencer <markster@linux-support.net>"); |