diff options
Diffstat (limited to 'drivers/dahdi/xpp/xbus-core.c')
-rw-r--r-- | drivers/dahdi/xpp/xbus-core.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c index d558a75..3d37f71 100644 --- a/drivers/dahdi/xpp/xbus-core.c +++ b/drivers/dahdi/xpp/xbus-core.c @@ -630,6 +630,7 @@ static int new_card(xbus_t *xbus, int subunits; int ret = 0; int remaining_ports; + const struct echoops *echoops; proto_table = xproto_get(type); if(!proto_table) { @@ -638,6 +639,18 @@ static int new_card(xbus_t *xbus, unit, type); return -EINVAL; } + echoops = proto_table->echoops; + if (echoops) { + XBUS_INFO(xbus, "Detected ECHO Canceler (%d)\n", unit); + if (ECHOOPS(xbus)) { + XBUS_NOTICE(xbus, + "CARD %d: tryies to define echoops (type %d) but we already have one. Ignored.\n", + unit, type); + return -EINVAL; + } + xbus->echo_state.echoops = echoops; + xbus->echo_state.xpd_idx = XPD_IDX(unit, 0); + } remaining_ports = ports; subunits = (ports + proto_table->ports_per_subunit - 1) / proto_table->ports_per_subunit; @@ -748,6 +761,11 @@ static int xpd_initialize(xpd_t *xpd) } xpd->card_present = 1; if (IS_PHONEDEV(xpd)) { + /* + * Set echo canceler channels (off) + * Asterisk will tell us when/if it's needed. + */ + CALL_PHONE_METHOD(echocancel_setmask, xpd, 0); CALL_PHONE_METHOD(card_state, xpd, 1); /* Turn on all channels */ } if(!xpd_setstate(xpd, XPD_STATE_READY)) { @@ -760,6 +778,34 @@ out: return ret; } +static int xbus_echocancel(xbus_t *xbus, int on) +{ + int unit; + int subunit; + xpd_t *xpd; + + if (!ECHOOPS(xbus)) + return 0; + for (unit = 0; unit < MAX_UNIT; unit++) { + xpd = xpd_byaddr(xbus, unit, 0); + if (!xpd || !IS_PHONEDEV(xpd)) + continue; + for (subunit = 0; subunit < MAX_SUBUNIT; subunit++) { + int ret; + + xpd = xpd_byaddr(xbus, unit, subunit); + if (!xpd || !IS_PHONEDEV(xpd)) + continue; + ret = echocancel_xpd(xpd, on); + if (ret < 0) { + XPD_ERR(xpd, "Fail in xbus_echocancel()\n"); + return ret; + } + } + } + return 0; +} + static int xbus_initialize(xbus_t *xbus) { int unit; @@ -807,6 +853,7 @@ static int xbus_initialize(xbus_t *xbus) goto err; } } + xbus_echocancel(xbus, 1); do_gettimeofday(&time_end); timediff = usec_diff(&time_end, &time_start); timediff /= 1000*100; @@ -1154,6 +1201,7 @@ void xbus_deactivate(xbus_t *xbus) return; xbus_request_sync(xbus, SYNC_MODE_NONE); /* no more ticks */ elect_syncer("deactivate"); + xbus_echocancel(xbus, 0); xbus_request_removal(xbus); XBUS_DBG(DEVICES, xbus, "[%s] Waiting for queues\n", xbus->label); xbus_command_queue_clean(xbus); |