summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wctdm24xxp
diff options
context:
space:
mode:
authorAlec L Davis <sivad.a@paradise.net.nz>2010-07-30 19:19:34 +0000
committerAlec L Davis <sivad.a@paradise.net.nz>2010-07-30 19:19:34 +0000
commite7391522dcb7c4146a41d07f0ee1e28f879ccda9 (patch)
tree232da4921cf14953b2a9641470986e51abb73640 /drivers/dahdi/wctdm24xxp
parente0e0b776b77031223c90f9fcadefe3efffab951d (diff)
wctdm24xxp: Prevent FXS Proslic staying in "Forward/Reverse OnHookTransfer" during call [One-liner summary of changes]
Now that the 3 second click after answering the call on an FXS port has been fixed, the side effect is that the Proslic during a call, still has the audio signal paths still powered on. Reading the Si3215 specs it reads that an extra ~20mA is consumed while in OHT mode. (closes issue #17764) Reported by: alecdavis Patches: wctdm24xxp_fxs_offhook.diff.txt uploaded by alecdavis (license 585) Tested by: alecdavis git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9070 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/wctdm24xxp')
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c165
1 files changed, 91 insertions, 74 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 60458eb..30ca640 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -1805,12 +1805,74 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
#undef MS_PER_CHECK_HOOK
}
+static void wctdm_fxs_hooksig(struct wctdm *wc, const int card, enum dahdi_txsig txsig)
+{
+ int x = 0;
+ unsigned long flags;
+ struct fxs *const fxs = &wc->mods[card].fxs;
+ spin_lock_irqsave(&fxs->lasttxhooklock, flags);
+ switch (txsig) {
+ case DAHDI_TXSIG_ONHOOK:
+ switch (wc->aspan->span.chans[card]->sig) {
+ case DAHDI_SIG_EM:
+ case DAHDI_SIG_FXOKS:
+ case DAHDI_SIG_FXOLS:
+ x = fxs->idletxhookstate;
+ break;
+ case DAHDI_SIG_FXOGS:
+ x = (POLARITY_XOR(card)) ?
+ SLIC_LF_RING_OPEN :
+ SLIC_LF_TIP_OPEN;
+ break;
+ }
+ break;
+ case DAHDI_TXSIG_OFFHOOK:
+ switch (wc->aspan->span.chans[card]->sig) {
+ case DAHDI_SIG_EM:
+ x = (POLARITY_XOR(card)) ?
+ SLIC_LF_ACTIVE_FWD :
+ SLIC_LF_ACTIVE_REV;
+ break;
+ default:
+ x = fxs->idletxhookstate;
+ break;
+ }
+ break;
+ case DAHDI_TXSIG_START:
+ x = SLIC_LF_RINGING;
+ break;
+ case DAHDI_TXSIG_KEWL:
+ x = SLIC_LF_OPEN;
+ break;
+ default:
+ spin_unlock_irqrestore(&fxs->lasttxhooklock, flags);
+ dev_notice(&wc->vb.pdev->dev,
+ "wctdm24xxp: Can't set tx state to %d\n", txsig);
+ return;
+ }
+
+ if (x != fxs->lasttxhook) {
+ fxs->lasttxhook = x | SLIC_LF_OPPENDING;
+ wc->sethook[card] = CMD_WR(LINE_STATE, fxs->lasttxhook);
+ spin_unlock_irqrestore(&fxs->lasttxhooklock, flags);
+
+ if (debug & DEBUG_CARD) {
+ dev_info(&wc->vb.pdev->dev, "Setting FXS hook state "
+ "to %d (%02x) intcount=%d\n", txsig, x,
+ wc->intcount);
+ }
+ } else {
+ spin_unlock_irqrestore(&fxs->lasttxhooklock, flags);
+ }
+}
+
static void wctdm_fxs_off_hook(struct wctdm *wc, const int card)
{
struct fxs *const fxs = &wc->mods[card].fxs;
if (debug & DEBUG_CARD)
- dev_info(&wc->vb.pdev->dev, "wctdm: Card %d Going off hook\n", card);
+ dev_info(&wc->vb.pdev->dev,
+ "fxs_off_hook: Card %d Going off hook\n", card);
switch (fxs->lasttxhook) {
case SLIC_LF_RINGING: /* Ringing */
case SLIC_LF_OHTRAN_FWD: /* Forward On Hook Transfer */
@@ -1821,7 +1883,9 @@ static void wctdm_fxs_off_hook(struct wctdm *wc, const int card)
SLIC_LF_ACTIVE_FWD;
break;
}
+ wctdm_fxs_hooksig(wc, card, DAHDI_TXSIG_OFFHOOK);
dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_OFFHOOK);
+
#ifdef DEBUG
if (robust)
wctdm_init_proslic(wc, card, 1, 0, 1);
@@ -1833,7 +1897,9 @@ static void wctdm_fxs_on_hook(struct wctdm *wc, const int card)
{
struct fxs *const fxs = &wc->mods[card].fxs;
if (debug & DEBUG_CARD)
- dev_info(&wc->vb.pdev->dev, "wctdm: Card %d Going on hook\n", card);
+ dev_info(&wc->vb.pdev->dev,
+ "fxs_on_hook: Card %d Going on hook\n", card);
+ wctdm_fxs_hooksig(wc, card, DAHDI_TXSIG_ONHOOK);
dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_ONHOOK);
fxs->oldrxhook = 0;
}
@@ -3237,29 +3303,33 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
fxs->idletxhookstate |= SLIC_LF_REVMASK;
x = fxs->lasttxhook & SLIC_LF_SETMASK;
x |= SLIC_LF_REVMASK;
- x = set_lasttxhook_interruptible(fxs, x, &wc->sethook[chan->chanpos - 1]);
- if ((debug & DEBUG_CARD) && x) {
- dev_info(&wc->vb.pdev->dev,
- "Channel %d TIMEOUT: Set Reverse "
- "Polarity\n", chan->chanpos - 1);
- } else if (debug & DEBUG_CARD) {
- dev_info(&wc->vb.pdev->dev,
- "Channel %d Set Reverse Polarity\n",
- chan->chanpos - 1);
+ if (x != fxs->lasttxhook) {
+ x = set_lasttxhook_interruptible(fxs, x, &wc->sethook[chan->chanpos - 1]);
+ if ((debug & DEBUG_CARD) && x) {
+ dev_info(&wc->vb.pdev->dev,
+ "Channel %d TIMEOUT: Set Reverse "
+ "Polarity\n", chan->chanpos - 1);
+ } else if (debug & DEBUG_CARD) {
+ dev_info(&wc->vb.pdev->dev,
+ "Channel %d Set Reverse Polarity\n",
+ chan->chanpos - 1);
+ }
}
} else {
fxs->idletxhookstate &= ~SLIC_LF_REVMASK;
x = fxs->lasttxhook & SLIC_LF_SETMASK;
x &= ~SLIC_LF_REVMASK;
- x = set_lasttxhook_interruptible(fxs, x, &wc->sethook[chan->chanpos - 1]);
- if ((debug & DEBUG_CARD) & x) {
- dev_info(&wc->vb.pdev->dev,
- "Channel %d TIMEOUT: Set Normal "
- "Polarity\n", chan->chanpos - 1);
- } else if (debug & DEBUG_CARD) {
- dev_info(&wc->vb.pdev->dev,
- "Channel %d Set Normal Polarity\n",
- chan->chanpos - 1);
+ if (x != fxs->lasttxhook) {
+ x = set_lasttxhook_interruptible(fxs, x, &wc->sethook[chan->chanpos - 1]);
+ if ((debug & DEBUG_CARD) & x) {
+ dev_info(&wc->vb.pdev->dev,
+ "Channel %d TIMEOUT: Set Normal "
+ "Polarity\n", chan->chanpos - 1);
+ } else if (debug & DEBUG_CARD) {
+ dev_info(&wc->vb.pdev->dev,
+ "Channel %d Set Normal Polarity\n",
+ chan->chanpos - 1);
+ }
}
}
break;
@@ -3527,60 +3597,7 @@ static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
dev_notice(&wc->vb.pdev->dev, "wctdm24xxp: Can't set tx state to %d\n", txsig);
}
} else if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
- int x = 0;
- unsigned long flags;
- struct fxs *const fxs = &wc->mods[chan->chanpos - 1].fxs;
- spin_lock_irqsave(&fxs->lasttxhooklock, flags);
- switch(txsig) {
- case DAHDI_TXSIG_ONHOOK:
- switch(chan->sig) {
- case DAHDI_SIG_EM:
- case DAHDI_SIG_FXOKS:
- case DAHDI_SIG_FXOLS:
- x = fxs->idletxhookstate;
- break;
- case DAHDI_SIG_FXOGS:
- if (POLARITY_XOR(chan->chanpos -1)) {
- x = SLIC_LF_RING_OPEN;
- } else {
- x = SLIC_LF_TIP_OPEN;
- }
- break;
- }
- break;
- case DAHDI_TXSIG_OFFHOOK:
- switch(chan->sig) {
- case DAHDI_SIG_EM:
- x = (POLARITY_XOR(chan->chanpos - 1)) ?
- SLIC_LF_ACTIVE_FWD :
- SLIC_LF_ACTIVE_REV;
- break;
- default:
- x = fxs->idletxhookstate;
- break;
- }
- break;
- case DAHDI_TXSIG_START:
- x = SLIC_LF_RINGING;
- break;
- case DAHDI_TXSIG_KEWL:
- x = SLIC_LF_OPEN;
- break;
- default:
- spin_unlock_irqrestore(&fxs->lasttxhooklock, flags);
- dev_notice(&wc->vb.pdev->dev, "wctdm24xxp: Can't set tx state to %d\n", txsig);
- return 0;
- }
-
- fxs->lasttxhook = x | SLIC_LF_OPPENDING;
- wc->sethook[chan->chanpos - 1] = CMD_WR(LINE_STATE, fxs->lasttxhook);
- spin_unlock_irqrestore(&fxs->lasttxhooklock, flags);
- if (debug & DEBUG_CARD) {
- dev_info(&wc->vb.pdev->dev, "Setting FXS hook state "
- "to %d (%02x) intcount=%d\n", txsig, x,
- wc->intcount);
- }
- } else {
+ wctdm_fxs_hooksig(wc, chan->chanpos - 1, txsig);
}
return 0;
}