summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wctdm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dahdi/wctdm.c')
-rw-r--r--drivers/dahdi/wctdm.c167
1 files changed, 104 insertions, 63 deletions
diff --git a/drivers/dahdi/wctdm.c b/drivers/dahdi/wctdm.c
index ba44fc6..49ed741 100644
--- a/drivers/dahdi/wctdm.c
+++ b/drivers/dahdi/wctdm.c
@@ -726,22 +726,23 @@ static int wctdm_proslic_verify_indirect_regs(struct wctdm *wc, int card)
static inline void wctdm_proslic_recheck_sanity(struct wctdm *wc, int card)
{
+ struct fxs *const fxs = &wc->mod[card].fxs;
int res;
/* Check loopback */
res = wc->reg1shadow[card];
- if (!res && (res != wc->mod[card].fxs.lasttxhook)) {
+ if (!res && (res != fxs->lasttxhook)) {
res = wctdm_getreg(wc, card, 8);
if (res) {
printk(KERN_NOTICE "Ouch, part reset, quickly restoring reality (%d)\n", card);
wctdm_init_proslic(wc, card, 1, 0, 1);
} else {
- if (wc->mod[card].fxs.palarms++ < MAX_ALARMS) {
+ if (fxs->palarms++ < MAX_ALARMS) {
printk(KERN_NOTICE "Power alarm on module %d, resetting!\n", card + 1);
- if (wc->mod[card].fxs.lasttxhook == SLIC_LF_RINGING)
- wc->mod[card].fxs.lasttxhook = SLIC_LF_ACTIVE_FWD;
- wctdm_setreg(wc, card, 64, wc->mod[card].fxs.lasttxhook);
+ if (fxs->lasttxhook == SLIC_LF_RINGING)
+ fxs->lasttxhook = SLIC_LF_ACTIVE_FWD;
+ wctdm_setreg(wc, card, 64, fxs->lasttxhook);
} else {
- if (wc->mod[card].fxs.palarms == MAX_ALARMS)
+ if (fxs->palarms == MAX_ALARMS)
printk(KERN_NOTICE "Too many power alarms on card %d, NOT resetting!\n", card + 1);
}
}
@@ -965,6 +966,7 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
{
+ struct fxs *const fxs = &wc->mod[card].fxs;
char res;
int hook;
@@ -973,57 +975,63 @@ static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
res = wc->reg0shadow[card];
hook = (res & 1);
- if (hook != wc->mod[card].fxs.lastrxhook) {
+ if (hook != fxs->lastrxhook) {
/* Reset the debounce (must be multiple of 4ms) */
- wc->mod[card].fxs.debounce = 8 * (4 * 8);
+ fxs->debounce = 8 * (4 * 8);
#if 0
- printk(KERN_DEBUG "Resetting debounce card %d hook %d, %d\n", card, hook, wc->mod[card].fxs.debounce);
+ printk(KERN_DEBUG "Resetting debounce card %d hook %d, %d\n",
+ card, hook, fxs->debounce);
#endif
} else {
- if (wc->mod[card].fxs.debounce > 0) {
- wc->mod[card].fxs.debounce-= 16 * DAHDI_CHUNKSIZE;
+ if (fxs->debounce > 0) {
+ fxs->debounce -= 16 * DAHDI_CHUNKSIZE;
#if 0
- printk(KERN_DEBUG "Sustaining hook %d, %d\n", hook, wc->mod[card].fxs.debounce);
+ printk(KERN_DEBUG "Sustaining hook %d, %d\n",
+ hook, fxs->debounce);
#endif
- if (!wc->mod[card].fxs.debounce) {
+ if (!fxs->debounce) {
#if 0
printk(KERN_DEBUG "Counted down debounce, newhook: %d...\n", hook);
#endif
- wc->mod[card].fxs.debouncehook = hook;
+ fxs->debouncehook = hook;
}
- if (!wc->mod[card].fxs.oldrxhook && wc->mod[card].fxs.debouncehook) {
+ if (!fxs->oldrxhook && fxs->debouncehook) {
/* Off hook */
#if 1
if (debug)
#endif
printk(KERN_DEBUG "wctdm: Card %d Going off hook\n", card);
- switch ( wc->mod[card].fxs.lasttxhook ) {
- case SLIC_LF_RINGING: /* Ringing */
- case SLIC_LF_OHTRAN_FWD: /* Forward On Hook Transfer */
- case SLIC_LF_OHTRAN_REV: /* Reverse On Hook Transfer */
- /* just detected OffHook, during Ringing or OnHookTransfer */
- wc->mod[card].fxs.idletxhookstate = POLARITY_XOR(card) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD; /* Active */
+ switch (fxs->lasttxhook) {
+ case SLIC_LF_RINGING:
+ case SLIC_LF_OHTRAN_FWD:
+ case SLIC_LF_OHTRAN_REV:
+ /* just detected OffHook, during
+ * Ringing or OnHookTransfer */
+ fxs->idletxhookstate =
+ POLARITY_XOR(card) ?
+ SLIC_LF_ACTIVE_REV :
+ SLIC_LF_ACTIVE_FWD;
break;
}
dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
if (robust)
wctdm_init_proslic(wc, card, 1, 0, 1);
- wc->mod[card].fxs.oldrxhook = 1;
+ fxs->oldrxhook = 1;
- } else if (wc->mod[card].fxs.oldrxhook && !wc->mod[card].fxs.debouncehook) {
+ } else if (fxs->oldrxhook && !fxs->debouncehook) {
/* On hook */
#if 1
if (debug)
#endif
printk(KERN_DEBUG "wctdm: Card %d Going on hook\n", card);
dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
- wc->mod[card].fxs.oldrxhook = 0;
+ fxs->oldrxhook = 0;
}
}
}
- wc->mod[card].fxs.lastrxhook = hook;
+ fxs->lastrxhook = hook;
}
DAHDI_IRQ_HANDLER(wctdm_interrupt)
@@ -1055,27 +1063,40 @@ DAHDI_IRQ_HANDLER(wctdm_interrupt)
for (x=0;x<4;x++) {
if (wc->cardflag & (1 << x) &&
(wc->modtype[x] == MOD_TYPE_FXS)) {
- if (wc->mod[x].fxs.lasttxhook == SLIC_LF_RINGING) {
+ struct fxs *const fxs = &wc->mod[x].fxs;
+ if (fxs->lasttxhook == SLIC_LF_RINGING) {
/* RINGing, prepare for OHT */
- wc->mod[x].fxs.ohttimer = OHT_TIMER << 3;
+ fxs->ohttimer = OHT_TIMER << 3;
/* logical XOR 3 variables
module parameter 'reversepolarity', global reverse all FXS lines.
ioctl channel variable fxs 'reversepolarity', Line Reversal Alert Signal if required.
ioctl channel variable fxs 'vmwi_lrev', VMWI pending.
*/
- wc->mod[x].fxs.idletxhookstate = POLARITY_XOR(x) ? SLIC_LF_OHTRAN_REV : SLIC_LF_OHTRAN_FWD;/* OHT mode when idle */
- } else {
- if (wc->mod[x].fxs.ohttimer) {
- wc->mod[x].fxs.ohttimer-= DAHDI_CHUNKSIZE;
- if (!wc->mod[x].fxs.ohttimer) {
- wc->mod[x].fxs.idletxhookstate = POLARITY_XOR(x) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD; /* Switch to Active : Reverse Forward */
- if ((wc->mod[x].fxs.lasttxhook == SLIC_LF_OHTRAN_FWD) || (wc->mod[x].fxs.lasttxhook == SLIC_LF_OHTRAN_REV )) {
- /* Apply the change if appropriate */
- wc->mod[x].fxs.lasttxhook = POLARITY_XOR(x) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD;
- wctdm_setreg(wc, x, 64, wc->mod[x].fxs.lasttxhook);
- }
- }
+
+ /* OHT mode when idle */
+ fxs->idletxhookstate = POLARITY_XOR(x) ?
+ SLIC_LF_OHTRAN_REV :
+ SLIC_LF_OHTRAN_FWD;
+ } else if (fxs->ohttimer) {
+ fxs->ohttimer -= DAHDI_CHUNKSIZE;
+ if (fxs->ohttimer)
+ continue;
+
+ /* Switch to Active : Reverse Forward */
+ fxs->idletxhookstate = POLARITY_XOR(x) ?
+ SLIC_LF_ACTIVE_REV :
+ SLIC_LF_ACTIVE_FWD;
+
+ if ((fxs->lasttxhook == SLIC_LF_OHTRAN_FWD) ||
+ (fxs->lasttxhook == SLIC_LF_OHTRAN_REV)) {
+ /* Apply the change if appropriate */
+ fxs->lasttxhook = POLARITY_XOR(x) ?
+ SLIC_LF_ACTIVE_REV :
+ SLIC_LF_ACTIVE_FWD;
+
+ wctdm_setreg(wc, x, 64,
+ fxs->lasttxhook);
}
}
}
@@ -1463,6 +1484,7 @@ static int wctdm_set_hwgain(struct wctdm *wc, int card, __s32 gain, __u32 tx)
static int set_vmwi(struct wctdm * wc, int chan_idx)
{
+ struct fxs *const fxs = &wc->mod[chan_idx].fxs;
if (wc->mod[chan_idx].fxs.vmwi_active_messages){
wc->mod[chan_idx].fxs.vmwi_lrev = (wc->mod[chan_idx].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_LREV)?1:0;
wc->mod[chan_idx].fxs.vmwi_hvdc = (wc->mod[chan_idx].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_HVDC)?1:0;
@@ -1485,16 +1507,16 @@ static int set_vmwi(struct wctdm * wc, int chan_idx)
if (POLARITY_XOR(chan_idx)) {
wc->mod[chan_idx].fxs.idletxhookstate |= SLIC_LF_REVMASK;
/* Do not set while currently ringing or open */
- if (wc->mod[chan_idx].fxs.lasttxhook != SLIC_LF_RINGING &&
- wc->mod[chan_idx ].fxs.lasttxhook != SLIC_LF_OPEN) {
- wc->mod[chan_idx ].fxs.lasttxhook |= SLIC_LF_REVMASK;
- wctdm_setreg(wc, chan_idx, 64, wc->mod[chan_idx].fxs.lasttxhook);
+ if ((fxs->lasttxhook != SLIC_LF_RINGING) &&
+ (fxs->lasttxhook != SLIC_LF_OPEN)) {
+ fxs->lasttxhook |= SLIC_LF_REVMASK;
+ wctdm_setreg(wc, chan_idx, 64, fxs->lasttxhook);
}
} else {
wc->mod[chan_idx].fxs.idletxhookstate &= ~SLIC_LF_REVMASK;
/* Do not set while currently ringing or open */
- if (wc->mod[chan_idx].fxs.lasttxhook != SLIC_LF_RINGING &&
- wc->mod[chan_idx].fxs.lasttxhook != SLIC_LF_OPEN) {
+ if ((fxs->lasttxhook != SLIC_LF_RINGING) &&
+ (fxs->lasttxhook != SLIC_LF_OPEN)) {
wc->mod[chan_idx].fxs.lasttxhook &= ~SLIC_LF_REVMASK;
wctdm_setreg(wc, chan_idx, 64, wc->mod[chan_idx].fxs.lasttxhook);
}
@@ -1859,6 +1881,7 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
struct wctdm_echo_coefs echoregs;
struct dahdi_hwgain hwgain;
struct wctdm *wc = chan->pvt;
+ struct fxs *const fxs = &wc->mod[chan->chanpos - 1].fxs;
int x;
switch (cmd) {
case DAHDI_ONHOOKTRANSFER:
@@ -1867,10 +1890,18 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
if (get_user(x, (__user int *) data))
return -EFAULT;
wc->mod[chan->chanpos - 1].fxs.ohttimer = x << 3;
- wc->mod[chan->chanpos - 1].fxs.idletxhookstate = POLARITY_XOR(chan->chanpos - 1) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD; /* Active mode when idle */
- if (wc->mod[chan->chanpos - 1].fxs.lasttxhook == SLIC_LF_ACTIVE_FWD || wc->mod[chan->chanpos - 1].fxs.lasttxhook == SLIC_LF_ACTIVE_REV) {
+
+ /* Active mode when idle */
+ fxs->idletxhookstate = POLARITY_XOR(chan->chanpos - 1) ?
+ SLIC_LF_ACTIVE_REV :
+ SLIC_LF_ACTIVE_FWD;
+
+ if ((fxs->lasttxhook == SLIC_LF_ACTIVE_FWD) ||
+ (fxs->lasttxhook == SLIC_LF_ACTIVE_REV)) {
/* Apply the change if appropriate */
- wc->mod[chan->chanpos - 1].fxs.lasttxhook = POLARITY_XOR(chan->chanpos - 1) ? SLIC_LF_OHTRAN_REV : SLIC_LF_OHTRAN_FWD;
+ fxs->lasttxhook = POLARITY_XOR(chan->chanpos - 1) ?
+ SLIC_LF_OHTRAN_REV :
+ SLIC_LF_OHTRAN_FWD;
wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
}
break;
@@ -1880,15 +1911,15 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
return -EINVAL;
/* Can't change polarity while ringing or when open */
- if ((wc->mod[chan->chanpos -1 ].fxs.lasttxhook == SLIC_LF_RINGING) ||
- (wc->mod[chan->chanpos -1 ].fxs.lasttxhook == SLIC_LF_OPEN))
+ if ((fxs->lasttxhook == SLIC_LF_RINGING) ||
+ (fxs->lasttxhook == SLIC_LF_OPEN))
return -EINVAL;
wc->mod[chan->chanpos - 1].fxs.reversepolarity = x;
if ( POLARITY_XOR(chan->chanpos - 1) )
- wc->mod[chan->chanpos - 1].fxs.lasttxhook |= SLIC_LF_REVMASK;
+ fxs->lasttxhook |= SLIC_LF_REVMASK;
else
- wc->mod[chan->chanpos - 1].fxs.lasttxhook &= ~SLIC_LF_REVMASK;
+ fxs->lasttxhook &= ~SLIC_LF_REVMASK;
wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
break;
case DAHDI_VMWI_CONFIG:
@@ -2017,7 +2048,11 @@ static int wctdm_close(struct dahdi_chan *chan)
struct wctdm *wc = chan->pvt;
wc->usecount--;
if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
- wc->mod[chan->chanpos - 1].fxs.idletxhookstate = POLARITY_XOR(chan->chanpos - 1) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD;
+ int idlehookstate;
+ idlehookstate = POLARITY_XOR(chan->chanpos - 1) ?
+ SLIC_LF_ACTIVE_REV :
+ SLIC_LF_ACTIVE_FWD;
+ wc->mod[chan->chanpos - 1].fxs.idletxhookstate = idlehookstate;
}
/* If we're dead, release us now */
if (!wc->usecount && wc->dead)
@@ -2045,45 +2080,51 @@ static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
printk(KERN_NOTICE "wcfxo: Can't set tx state to %d\n", txsig);
}
} else {
+ struct fxs *const fxs = &wc->mod[chan->chanpos - 1].fxs;
switch(txsig) {
case DAHDI_TXSIG_ONHOOK:
switch(chan->sig) {
case DAHDI_SIG_FXOKS:
case DAHDI_SIG_FXOLS:
- wc->mod[chan->chanpos-1].fxs.lasttxhook = (wc->mod[chan->chanpos-1].fxs.vmwi_hvac ? SLIC_LF_RINGING : wc->mod[chan->chanpos-1].fxs.idletxhookstate);
+ fxs->lasttxhook = fxs->vmwi_hvac ?
+ SLIC_LF_RINGING :
+ fxs->idletxhookstate;
break;
case DAHDI_SIG_EM:
- wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
+ fxs->lasttxhook = fxs->idletxhookstate;
break;
case DAHDI_SIG_FXOGS:
- wc->mod[chan->chanpos-1].fxs.lasttxhook = SLIC_LF_TIP_OPEN;
+ fxs->lasttxhook = SLIC_LF_TIP_OPEN;
break;
}
break;
case DAHDI_TXSIG_OFFHOOK:
switch(chan->sig) {
case DAHDI_SIG_EM:
- wc->mod[chan->chanpos-1].fxs.lasttxhook = SLIC_LF_ACTIVE_REV;
+ fxs->lasttxhook = SLIC_LF_ACTIVE_REV;
break;
default:
- wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
+ fxs->lasttxhook = fxs->idletxhookstate;
break;
}
break;
case DAHDI_TXSIG_START:
- wc->mod[chan->chanpos-1].fxs.lasttxhook = SLIC_LF_RINGING;
+ fxs->lasttxhook = SLIC_LF_RINGING;
break;
case DAHDI_TXSIG_KEWL:
- wc->mod[chan->chanpos-1].fxs.lasttxhook = SLIC_LF_OPEN;
+ fxs->lasttxhook = SLIC_LF_OPEN;
break;
default:
printk(KERN_NOTICE "wctdm: Can't set tx state to %d\n", txsig);
}
- if (debug)
- printk(KERN_DEBUG "Setting FXS hook state to %d (%02x)\n", txsig, wc->mod[chan->chanpos-1].fxs.lasttxhook);
+ if (debug) {
+ printk(KERN_DEBUG
+ "Setting FXS hook state to %d (%02x)\n",
+ txsig, fxs->lasttxhook);
+ }
#if 1
- wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos-1].fxs.lasttxhook);
+ wctdm_setreg(wc, chan->chanpos - 1, 64, fxs->lasttxhook);
#endif
}
return 0;