diff options
Diffstat (limited to 'kernel/zaptel-base.c')
-rw-r--r-- | kernel/zaptel-base.c | 47 |
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]); |