summaryrefslogtreecommitdiff
path: root/kernel/zaptel-base.c
diff options
context:
space:
mode:
authordbailey <dbailey@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-04-10 22:25:30 +0000
committerdbailey <dbailey@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-04-10 22:25:30 +0000
commit0ecae3e7460d4520882e8c73fad31326ff91a9b9 (patch)
tree7ec5db2503d36e60603c0c0b972ca09a2ee58198 /kernel/zaptel-base.c
parent752cdab6380dd4fdff979255e9d0bcd8695299ed (diff)
Correct problem where drivers implementing echocan_with_params was not getting called
to disable the echo canceller git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4168 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'kernel/zaptel-base.c')
-rw-r--r--kernel/zaptel-base.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/kernel/zaptel-base.c b/kernel/zaptel-base.c
index dbf4520..59d08e4 100644
--- a/kernel/zaptel-base.c
+++ b/kernel/zaptel-base.c
@@ -995,6 +995,22 @@ static void reset_conf(struct zt_chan *chan)
}
+static inline int hw_echocancel_off(struct zt_chan *chan)
+{
+ struct zt_echocanparams ecp;
+
+ int ret = -ENODEV;
+ if (chan->span) {
+ if (chan->span->echocan) {
+ ret = chan->span->echocan(chan, 0);
+ } else if (chan->span->echocan_with_params) {
+ memset(&ecp, 0, sizeof(ecp)); /* Sets tap length to 0 */
+ ret = chan->span->echocan_with_params(chan, &ecp, NULL);
+ }
+ }
+ return ret;
+}
+
static void close_channel(struct zt_chan *chan)
{
unsigned long flags;
@@ -1074,8 +1090,7 @@ static void close_channel(struct zt_chan *chan)
spin_unlock_irqrestore(&chan->lock, flags);
- if (chan->span && chan->span->echocan)
- chan->span->echocan(chan, 0);
+ hw_echocancel_off(chan);
if (rxgain)
kfree(rxgain);
@@ -2376,8 +2391,7 @@ static int initialize_channel(struct zt_chan *chan)
spin_unlock_irqrestore(&chan->lock, flags);
set_tone_zone(chan, -1);
- if (chan->span && chan->span->echocan)
- chan->span->echocan(chan, 0);
+ hw_echocancel_off(chan);
if (rxgain)
kfree(rxgain);
@@ -4597,8 +4611,7 @@ static int ioctl_echocancel(struct zt_chan *chan, struct zt_echocanparams *ecp,
chan->echolastupdate = 0;
chan->echotimer = 0;
spin_unlock_irqrestore(&chan->lock, flags);
- if (chan->span && chan->span->echocan)
- chan->span->echocan(chan, 0);
+ hw_echocancel_off(chan);
if (tec)
echo_can_free(tec);
@@ -4629,14 +4642,10 @@ static int ioctl_echocancel(struct zt_chan *chan, struct zt_echocanparams *ecp,
/* attempt to use the span's echo canceler; fall back to built-in
if it fails (but not if an error occurs) */
if (chan->span) {
- if (ecp->param_count) {
- if (chan->span->echocan_with_params)
- ret = chan->span->echocan_with_params(chan, ecp, params);
- } else if (chan->span->echocan) {
+ if (chan->span->echocan_with_params)
+ ret = chan->span->echocan_with_params(chan, ecp, params);
+ else if (!ecp->param_count && chan->span->echocan)
ret = chan->span->echocan(chan, ecp->tap_length);
- } else if (chan->span->echocan_with_params) {
- ret = chan->span->echocan_with_params(chan, ecp, NULL);
- }
}
if (ret == -ENODEV) {
@@ -4745,8 +4754,7 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm
/* Disable any native echo cancellation as well */
spin_unlock_irqrestore(&chan->lock, flags);
- if (chan->span && chan->span->echocan)
- chan->span->echocan(chan, 0);
+ hw_echocancel_off(chan);
if (rxgain)
kfree(rxgain);
@@ -4798,8 +4806,8 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm
chan->gainalloc = 0;
chan->flags &= ~ZT_FLAG_AUDIO;
chan->flags |= (ZT_FLAG_PPP | ZT_FLAG_HDLC | ZT_FLAG_FCS);
- if (chan->span && chan->span->echocan)
- chan->span->echocan(chan, 0);
+ hw_echocancel_off(chan);
+
if (tec)
echo_can_free(tec);
} else
@@ -5120,6 +5128,11 @@ int zt_register(struct zt_span *span, int prefmaster)
span->deflaw = ZT_LAW_MULAW;
}
+ if (span->echocan && span->echocan_with_params) {
+ printk("zaptel: Span %s implements both echocan and echocan_with_params functions, preserving only echocan_with_params, please fix driver!\n", span->name);
+ span->echocan = NULL;
+ }
+
for (x=0;x<span->channels;x++) {
span->chans[x].span = span;
zt_chan_reg(&span->chans[x]);