diff options
author | Shaun Ruffell <sruffell@digium.com> | 2009-04-29 18:24:04 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2009-04-29 18:24:04 +0000 |
commit | 5f94a3b91de2c3835d6852d59cab9f6876177156 (patch) | |
tree | 4c25956b6ecdcd5b902ac80b40237bc3e938be44 /drivers/dahdi/wcb4xxp | |
parent | 4a192a3e8f16ed6143377b5726e1fb53b446f5e9 (diff) |
echocan: Improve interface for echo cancelers.
Echo cancelers are now able to report if they are able to automatically disable
their NLP portions in the presence of tones in the audio stream. Also, the
interface is changed to allow user space to just disable the NLP portion of the
echo canceler. These changes improve fax and modem handling in DAHDI.
This commit merges in the changes on
http://svn.digium.com/svn/dahdi/linux/team/kpfleming/echocan_work
Patch by: kpfleming
Also contains improvements to CED tone detection.
(closes issue #13286)
Reported by: viniciusfontes
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@6529 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/wcb4xxp')
-rw-r--r-- | drivers/dahdi/wcb4xxp/base.c | 73 | ||||
-rw-r--r-- | drivers/dahdi/wcb4xxp/wcb4xxp.h | 1 |
2 files changed, 53 insertions, 21 deletions
diff --git a/drivers/dahdi/wcb4xxp/base.c b/drivers/dahdi/wcb4xxp/base.c index 0fea600..d07ce7c 100644 --- a/drivers/dahdi/wcb4xxp/base.c +++ b/drivers/dahdi/wcb4xxp/base.c @@ -114,6 +114,20 @@ struct devtype { static struct devtype wcb4xxp = { "Wildcard B410P", 0 }; +static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec); +static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); + +static const struct dahdi_echocan_features my_ec_features = { + .NLP_automatic = 1, + .CED_tx_detect = 1, + .CED_rx_detect = 1, +}; + +static const struct dahdi_echocan_ops my_ec_ops = { + .name = "HWEC", + .echocan_free = echocan_free, +}; #if 0 static const char *wcb4xxp_rcsdata = "$RCSfile: base.c,v $ $Revision$"; @@ -1884,33 +1898,50 @@ static void b4xxp_update_leds(struct b4xxp *b4) } } -static int b4xxp_echocan(struct dahdi_chan *chan, int eclen) +static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec) { - struct b4xxp *b4 = chan->pvt; + struct b4xxp_span *bspan = chan->span->pvt; int channel; - int unit; - - if (chan->chanpos != 3) - unit = chan->chanpos - 1; - else - return 0; - - channel = (chan->span->offset * 8) + ((chan->chanpos - 1) * 4) + 1; - - if (eclen) { /* Enable */ - if (DBG_EC) - printk("Enabling echo cancellation on chan %d span %d\n", chan->chanpos, chan->span->offset); - ec_write(b4, unit, channel, 0x7e); - } else { /* Disable */ - if (DBG_EC) - printk("Disabling echo cancellation on chan %d span %d\n", chan->chanpos, chan->span->offset); - ec_write(b4, unit, channel, 0x01); + + if (chan->chanpos == 3) { + printk(KERN_WARNING "Cannot enable echo canceller on D channel of span %d; failing request\n", chan->span->offset); + return -EINVAL; } + + if (ecp->param_count > 0) { + printk(KERN_WARNING "wcb4xxp echo canceller does not support parameters; failing request\n"); + return -EINVAL; + } + + *ec = &bspan->ec[chan->chanpos]; + (*ec)->ops = &my_ec_ops; + (*ec)->features = my_ec_features; + + if (DBG_EC) + printk("Enabling echo cancellation on chan %d span %d\n", chan->chanpos, chan->span->offset); + + channel = (chan->span->offset * 8) + ((chan->chanpos - 1) * 4) + 1; - return 0; + ec_write(bspan->parent, chan->chanpos - 1, channel, 0x7e); + return 0; } +static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec) +{ + struct b4xxp_span *bspan = chan->span->pvt; + int channel; + + memset(ec, 0, sizeof(*ec)); + + if (DBG_EC) + printk("Disabling echo cancellation on chan %d span %d\n", chan->chanpos, chan->span->offset); + + channel = (chan->span->offset * 8) + ((chan->chanpos - 1) * 4) + 1; + + ec_write(bspan->parent, chan->chanpos - 1, channel, 0x01); +} /* * Filesystem and DAHDI interfaces @@ -2140,7 +2171,7 @@ static void init_spans(struct b4xxp *b4) bspan->span.ioctl = b4xxp_ioctl; bspan->span.hdlc_hard_xmit = b4xxp_hdlc_hard_xmit; if (vpmsupport) - bspan->span.echocan = b4xxp_echocan; + bspan->span.echocan_create = echocan_create; /* HDLC stuff */ bspan->sigchan = NULL; diff --git a/drivers/dahdi/wcb4xxp/wcb4xxp.h b/drivers/dahdi/wcb4xxp/wcb4xxp.h index 5c930da..4542a2d 100644 --- a/drivers/dahdi/wcb4xxp/wcb4xxp.h +++ b/drivers/dahdi/wcb4xxp/wcb4xxp.h @@ -411,6 +411,7 @@ struct b4xxp_span { struct dahdi_span span; /* zaptel span info for this span */ struct dahdi_chan *chans[WCB4XXP_CHANNELS_PER_SPAN]; /* Individual channels */ + struct dahdi_echocan_state ec[WCB4XXP_CHANNELS_PER_SPAN]; /* echocan state for each channel */ struct dahdi_chan _chans[WCB4XXP_CHANNELS_PER_SPAN]; /* Backing memory */ }; |