[svn-commits] kpfleming: branch linux/kpfleming/echocan_work r6494 - in /linux/team/kpflemi...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Apr 27 09:30:30 CDT 2009


Author: kpfleming
Date: Mon Apr 27 09:30:26 2009
New Revision: 6494

URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=6494
Log:
improve new echocan API a bit to add some parameters that hw echocans need for andling their state structures

convert wcb4xxp, wct4xxp and wctdm24xxp over to new echocan API... still need to finish wcte12xp

fix up some API function names to match what they really do, and add a specific events-only echocan function for hwecs to use to report events


Modified:
    linux/team/kpfleming/echocan_work/drivers/dahdi/adt_lec.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi-base.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_jpah.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_kb1.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_mg2.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_oslec.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec2.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/dahdi_echocan_hpec.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/base.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/wcb4xxp.h
    linux/team/kpfleming/echocan_work/drivers/dahdi/wct4xxp/base.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/wctdm24xxp/base.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
    linux/team/kpfleming/echocan_work/include/dahdi/kernel.h

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/adt_lec.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/adt_lec.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/adt_lec.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/adt_lec.c Mon Apr 27 09:30:26 2009
@@ -38,6 +38,8 @@
 	unsigned int x;
 	char *c;
 
+	params->tap_length = ecp->tap_length;
+
 	for (x = 0; x < ecp->param_count; x++) {
 		for (c = p[x].name; *c; c++)
 			*c = tolower(*c);

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi-base.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi-base.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi-base.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi-base.c Mon Apr 27 09:30:26 2009
@@ -1076,25 +1076,6 @@
 }
 
 
-static inline int hw_echocancel_off(struct dahdi_chan *chan)
-{
-	int ret = 0;
-
-	if (!chan->span)
-		return -ENODEV;
-
-	if (chan->span->echocan) {
-		ret = chan->span->echocan(chan, 0);
-	} else if (chan->span->echocan_with_params) {
-		struct dahdi_echocanparams ecp = {
-			.tap_length = 0,
-		};
-		ret = chan->span->echocan_with_params(chan, &ecp, NULL);
-	}
-
-	return ret;
-}
-
 static const struct dahdi_echocan_factory *find_echocan(const char *name)
 {
 	struct ecfactory *cur;
@@ -1153,7 +1134,8 @@
 static void release_echocan(const struct dahdi_echocan_factory *ec)
 {
 #ifdef USE_ECHOCAN_REFCOUNT
-	module_put(ec->owner);
+	if (ec)
+		module_put(ec->owner);
 #endif
 }
 
@@ -1248,13 +1230,11 @@
 		chan->span->dacs(chan, NULL);
 
 	if (ec_state) {
-		ec_state->ops->echocan_free(ec_state);
+		ec_state->ops->echocan_free(chan, ec_state);
 		release_echocan(ec_current);
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
-
-	hw_echocancel_off(chan);
 
 	if (rxgain)
 		kfree(rxgain);
@@ -2554,15 +2534,13 @@
 	}
 
 	if (ec_state) {
-		ec_state->ops->echocan_free(ec_state);
+		ec_state->ops->echocan_free(chan, ec_state);
 		release_echocan(ec_current);
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
 
 	set_tone_zone(chan, -1);
-
-	hw_echocancel_off(chan);
 
 	if (rxgain)
 		kfree(rxgain);
@@ -4868,19 +4846,12 @@
 		chan->ec_current = NULL;
 		spin_unlock_irqrestore(&chan->lock, flags);
 		if (ec_state) {
-			ec_state->ops->echocan_free(ec_state);
+			ec_state->ops->echocan_free(chan, ec_state);
 			release_echocan(ec_current);
 		}
-		hw_echocancel_off(chan);
 
 		return 0;
 	}
-
-	/* if parameters were supplied and this channel's span provides an echocan,
-	   but not one that takes params, then we must punt here and return an error */
-	if (ecp->param_count && chan->span && chan->span->echocan &&
-	    !chan->span->echocan_with_params)
-		return -EINVAL;
 
 	params = kmalloc(sizeof(params[0]) * DAHDI_MAX_ECHOCANPARAMS, GFP_KERNEL);
 
@@ -4894,6 +4865,7 @@
 		goto exit_with_free;
 	}
 
+	/* free any echocan that may be on the channel already */
 	spin_lock_irqsave(&chan->lock, flags);
 	ec_state = chan->ec_state;
 	chan->ec_state = NULL;
@@ -4901,34 +4873,31 @@
 	chan->ec_current = NULL;
 	spin_unlock_irqrestore(&chan->lock, flags);
 	if (ec_state) {
-		ec_state->ops->echocan_free(ec_state);
+		ec_state->ops->echocan_free(chan, ec_state);
 		release_echocan(ec_current);
 	}
 
+	switch (ecp->tap_length) {
+	case 32:
+	case 64:
+	case 128:
+	case 256:
+	case 512:
+	case 1024:
+		break;
+	default:
+		ecp->tap_length = deftaps;
+	}
+
 	ret = -ENODEV;
+	ec_current = NULL;
 
 	/* 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 (chan->span->echocan_with_params)
-			ret = chan->span->echocan_with_params(chan, ecp, params);
-		else if (chan->span->echocan)
-			ret = chan->span->echocan(chan, ecp->tap_length);
-	}
+	if (chan->span && chan->span->echocan_create)
+		ret = chan->span->echocan_create(chan, ecp, params, &ec);
 
 	if ((ret == -ENODEV) && chan->ec_factory) {
-		switch (ecp->tap_length) {
-		case 32:
-		case 64:
-		case 128:
-		case 256:
-		case 512:
-		case 1024:
-			break;
-		default:
-			ecp->tap_length = deftaps;
-		}
-
 #ifdef USE_ECHOCAN_REFCOUNT
 		/* try to get another reference to the module providing
 		   this channel's echo canceler */
@@ -4942,7 +4911,7 @@
 		   an echo canceler instance if possible */
 		ec_current = chan->ec_factory;
 
-		ret = ec_current->echocan_create(ecp, params, &ec);
+		ret = ec_current->echocan_create(chan, ecp, params, &ec);
 		if (ret) {
 			release_echocan(ec_current);
 
@@ -4950,12 +4919,14 @@
 		}
 		if (!ec) {
 			module_printk(KERN_ERR, "%s failed to allocate an " \
-				"dahdi_echocan_state instance.\n",
-				ec_current->name);
+				      "dahdi_echocan_state instance.\n",
+				      ec_current->name);
 			ret = -EFAULT;
 			goto exit_with_free;
 		}
-
+	}
+
+	if (ec) {
 		spin_lock_irqsave(&chan->lock, flags);
 		chan->ec_current = ec_current;
 		chan->ec_state = ec;
@@ -5105,12 +5076,9 @@
 			spin_unlock_irqrestore(&chan->lock, flags);
 
 			if (ec_state) {
-				ec_state->ops->echocan_free(ec_state);
+				ec_state->ops->echocan_free(chan, ec_state);
 				release_echocan(ec_current);
 			}
-
-			/* Disable any native echo cancellation as well */
-			hw_echocancel_off(chan);
 
 			if (rxgain)
 				kfree(rxgain);
@@ -5159,10 +5127,9 @@
 					chan->gainalloc = 0;
 					chan->flags &= ~DAHDI_FLAG_AUDIO;
 					chan->flags |= (DAHDI_FLAG_PPP | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS);
-					hw_echocancel_off(chan);
 
 					if (tec) {
-						tec->ops->echocan_free(tec);
+						tec->ops->echocan_free(chan, tec);
 						release_echocan(ec_current);
 					}
 				} else
@@ -5521,13 +5488,6 @@
 		span->deflaw = DAHDI_LAW_MULAW;
 	}
 
-	if (span->echocan && span->echocan_with_params) {
-		module_printk(KERN_NOTICE, "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;
 		dahdi_chan_reg(span->chans[x]);
@@ -6679,19 +6639,25 @@
 				rxchunk[x] = DAHDI_LIN2X((int)rxlin, ss);
 			}
 		} else if (ss->ec_state->status.mode != ECHO_MODE_IDLE) {
-			short rxlins[DAHDI_CHUNKSIZE], txlins[DAHDI_CHUNKSIZE];
-
-			for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
-				rxlins[x] = DAHDI_XLAW(rxchunk[x], ss);
-				txlins[x] = DAHDI_XLAW(txchunk[x], ss);
-			}
 			ss->ec_state->events.all = 0;
-			ss->ec_state->ops->echocan_array_update(ss->ec_state, rxlins, txlins, DAHDI_CHUNKSIZE);
-			if (ss->ec_state->events.all) {
+
+			if (ss->ec_state->ops->echocan_process) {
+				short rxlins[DAHDI_CHUNKSIZE], txlins[DAHDI_CHUNKSIZE];
+
+				for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
+					rxlins[x] = DAHDI_XLAW(rxchunk[x], ss);
+					txlins[x] = DAHDI_XLAW(txchunk[x], ss);
+				}
+				ss->ec_state->ops->echocan_process(ss->ec_state, rxlins, txlins, DAHDI_CHUNKSIZE);
+
+				for (x = 0; x < DAHDI_CHUNKSIZE; x++)
+					rxchunk[x] = DAHDI_LIN2X((int) rxlins[x], ss);
+			} else if (ss->ec_state->ops->echocan_events)
+				ss->ec_state->ops->echocan_events(ss->ec_state);
+
+			if (ss->ec_state->events.all)
 				process_echocan_events(ss);
-			}
-			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
-				rxchunk[x] = DAHDI_LIN2X((int) rxlins[x], ss);
+
 		}
 #if defined(CONFIG_DAHDI_MMX) || defined(ECHO_CAN_FP)
 		kernel_fpu_end();

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_jpah.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_jpah.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_jpah.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_jpah.c Mon Apr 27 09:30:26 2009
@@ -40,10 +40,10 @@
 #define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
 #define debug_printk(level, fmt, args...) if (debug >= level) printk("%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec);
-static void echo_can_free(struct dahdi_echocan_state *ec);
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
 static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
 
 static const struct dahdi_echocan_factory my_factory = {
@@ -55,7 +55,7 @@
 static const struct dahdi_echocan_ops my_ops = {
 	.name = "JPAH",
 	.echocan_free = echo_can_free,
-	.echocan_array_update = echo_can_array_update,
+	.echocan_process = echo_can_process,
 	.echocan_traintap = echo_can_traintap,
 };
 
@@ -66,8 +66,8 @@
 
 #define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec)
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
 {
 	struct ec_pvt *pvt;
 
@@ -86,14 +86,14 @@
 	return 0;
 }
 
-static void echo_can_free(struct dahdi_echocan_state *ec)
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 
 	kfree(pvt);
 }
 
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 	u32 x;

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_kb1.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_kb1.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_kb1.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_kb1.c Mon Apr 27 09:30:26 2009
@@ -142,10 +142,10 @@
 	short *buf_d;			
 } echo_can_cb_s;
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec);
-static void echo_can_free(struct dahdi_echocan_state *ec);
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
 static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
 static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable);
 
@@ -162,7 +162,7 @@
 static const struct dahdi_echocan_ops my_ops = {
 	.name = "KB1",
 	.echocan_free = echo_can_free,
-	.echocan_array_update = echo_can_array_update,
+	.echocan_process = echo_can_process,
 	.echocan_traintap = echo_can_traintap,
 	.echocan_NLP_toggle = echocan_NLP_toggle,
 };
@@ -329,7 +329,7 @@
 
 }
 
-static void echo_can_free(struct dahdi_echocan_state *ec)
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 
@@ -615,7 +615,7 @@
 	return u;
 }
 
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 	u32 x;
@@ -628,8 +628,8 @@
 	}
 }
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec)
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
 {
 	int maxy;
 	int maxu;

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_mg2.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_mg2.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_mg2.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_mg2.c Mon Apr 27 09:30:26 2009
@@ -174,10 +174,10 @@
 	short *buf_d;			
 } echo_can_cb_s;
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec);
-static void echo_can_free(struct dahdi_echocan_state *ec);
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
 static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
 static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable);
 
@@ -194,7 +194,7 @@
 static const struct dahdi_echocan_ops my_ops = {
 	.name = "MG2",
 	.echocan_free = echo_can_free,
-	.echocan_array_update = echo_can_array_update,
+	.echocan_process = echo_can_process,
 	.echocan_traintap = echo_can_traintap,
 	.echocan_NLP_toggle = echocan_NLP_toggle,
 };
@@ -376,7 +376,7 @@
 
 }
 
-static void echo_can_free(struct dahdi_echocan_state *ec)
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 
@@ -755,7 +755,7 @@
 	return u;
 }
 
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 	u32 x;
@@ -768,8 +768,8 @@
 	}
 }
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec)
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
 {
 	int maxy;
 	int maxu;

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_oslec.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_oslec.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_oslec.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_oslec.c Mon Apr 27 09:30:26 2009
@@ -37,10 +37,10 @@
 
 #define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec);
-static void echo_can_free(struct dahdi_echocan_state *ec);
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
 static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
 
 static const struct dahdi_echocan_factory my_factory = {
@@ -52,7 +52,7 @@
 static const struct dahdi_echocan_ops my_ops = {
 	.name = "OSLEC",
 	.echocan_free = echo_can_free,
-	.echocan_array_update = echo_can_array_update,
+	.echocan_process = echo_can_process,
 	.echocan_traintap = echo_can_traintap,
 };
 
@@ -63,7 +63,7 @@
 
 #define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
 
-static void echo_can_free(struct dahdi_echocan_state *ec)
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 
@@ -71,7 +71,7 @@
 	kfree(pvt);
 }
 
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 	u32 SampleNum;
@@ -84,8 +84,8 @@
 	}
 }
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec)
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
 {
 	struct ec_pvt *pvt;
 

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec.c Mon Apr 27 09:30:26 2009
@@ -80,10 +80,10 @@
 #define MIN_RX_POWER_FOR_ADAPTION   64
 */
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec);
-static void echo_can_free(struct dahdi_echocan_state *ec);
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
 static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
 static void echocan_NLP_toggle(struct dahdi_echocan_state *ec, unsigned int enable);
 
@@ -100,7 +100,7 @@
 static const struct dahdi_echocan_ops my_ops = {
 	.name = "SEC",
 	.echocan_free = echo_can_free,
-	.echocan_array_update = echo_can_array_update,
+	.echocan_process = echo_can_process,
 	.echocan_traintap = echo_can_traintap,
 	.echocan_NLP_toggle = echocan_NLP_toggle,
 };
@@ -137,8 +137,8 @@
 
 #define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec)
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
 {
 	struct ec_pvt *pvt;
 	size_t size;
@@ -175,7 +175,7 @@
 	return 0;
 }
 
-static void echo_can_free(struct dahdi_echocan_state *ec)
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 
@@ -291,7 +291,7 @@
 	return clean_rx;
 }
 
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 	u32 x;

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec2.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec2.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec2.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi_echocan_sec2.c Mon Apr 27 09:30:26 2009
@@ -76,10 +76,10 @@
 /* #define MIN_TX_POWER_FOR_ADAPTION 4096
 #define MIN_RX_POWER_FOR_ADAPTION 64 */
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec);
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
 static void echo_can_free(struct dahdi_echocan_state *ec);
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size);
 static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
 
 static const struct dahdi_echocan_factory my_factory = {
@@ -91,7 +91,7 @@
 static const struct dahdi_echocan_ops my_ops = {
 	.name = "SEC2",
 	.echocan_free = echo_can_free,
-	.echocan_array_update = echo_can_array_update,
+	.echocan_process = echo_can_process,
 	.echocan_traintap = echo_can_traintap,
 };
 
@@ -127,8 +127,8 @@
 
 #define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec)
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
 {
 	struct ec_pvt *pvt;
 	size_t size;
@@ -293,7 +293,7 @@
 	return clean_rx;
 }
 
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, u32 size)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 	u32 x;

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/dahdi_echocan_hpec.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/dahdi_echocan_hpec.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/dahdi_echocan_hpec.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/dahdi_echocan_hpec.c Mon Apr 27 09:30:26 2009
@@ -36,10 +36,10 @@
 #include "hpec_user.h"
 #include "hpec.h"
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec);
-static void echo_can_free(struct dahdi_echocan_state *ec);
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, __u32 size);
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, __u32 size);
 static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
 
 static const struct dahdi_echocan_factory my_factory = {
@@ -57,7 +57,7 @@
 static const struct dahdi_echocan_ops my_ops = {
 	.name = "HPEC",
 	.echocan_free = echo_can_free,
-	.echocan_array_update = echo_can_array_update,
+	.echocan_process = echo_can_process,
 	.echocan_traintap = echo_can_traintap,
 };
 
@@ -99,7 +99,7 @@
 	kfree(ptr);
 }
 
-static void echo_can_free(struct dahdi_echocan_state *ec)
+static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 
@@ -107,7 +107,7 @@
 	kfree(pvt);
 }
 
-static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, const short *iref, __u32 size)
+static void echo_can_process(struct dahdi_echocan_state *ec, short *isig, const short *iref, __u32 size)
 {
 	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 
@@ -116,8 +116,8 @@
 
 DECLARE_MUTEX(alloc_lock);
 
-static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct dahdi_echocan_state **ec)
+static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			   struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
 {
 	struct ec_pvt *pvt;
 

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/base.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/base.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/base.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/base.c Mon Apr 27 09:30:26 2009
@@ -114,6 +114,20 @@
 
 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 int b4xxp_echocan(struct dahdi_chan *chan, int eclen)
-{
-	struct b4xxp *b4 = chan->pvt;
+static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			  struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
+{
+	struct b4xxp_span *bspan = chan->span->pvt;
 	int channel;
-	int unit; 
-	
-	if (chan->chanpos != 3) 
-		unit = chan->chanpos - 1;
-	else
-		return 0;
-	
+
+	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;
 	
-	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);
-	}
+	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;
 	
-	return 0;
-
-}
-
+	ec_write(bspan->parent, chan->chanpos - 1, channel, 0x01);
+}
 
 /*
  * Filesystem and DAHDI interfaces
@@ -2140,7 +2171,7 @@
 		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;

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/wcb4xxp.h
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/wcb4xxp.h?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/wcb4xxp.h (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/wcb4xxp/wcb4xxp.h Mon Apr 27 09:30:26 2009
@@ -411,6 +411,7 @@
 
 	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 */
 };
 

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/wct4xxp/base.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/wct4xxp/base.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/wct4xxp/base.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/wct4xxp/base.c Mon Apr 27 09:30:26 2009
@@ -283,6 +283,7 @@
 	struct work_struct swork;
 #endif	
 	struct dahdi_chan *chans[32];		/* Individual channels */
+	struct dahdi_echocan_state *ec[32];	/* Echocan state for each channel */
 };
 
 struct t4 {
@@ -345,12 +346,38 @@
 
 #define T4_VPM_PRESENT (1 << 28)
 
-
 #ifdef VPM_SUPPORT
 static void t4_vpm400_init(struct t4 *wc);
 static void t4_vpm450_init(struct t4 *wc);
 static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold);
-#endif
+
+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 vpm400m_ec_features = {
+	.NLP_automatic = 1,
+	.CED_tx_detect = 1,
+	.CED_rx_detect = 1,
+};
+
+static const struct dahdi_echocan_features vpm450m_ec_features = {
+	.NLP_automatic = 1,
+	.CED_tx_detect = 1,
+	.CED_rx_detect = 1,
+};
+
+static const struct dahdi_echocan_ops vpm400m_ec_ops = {
+	.name = "VPM400M",
+	.echocan_free = echocan_free,
+};
+
+static const struct dahdi_echocan_ops vpm450m_ec_ops = {
+	.name = "VPM450M",
+	.echocan_free = echocan_free,
+};
+#endif
+
 static void __set_clear(struct t4 *wc, int span);
 static int t4_startup(struct dahdi_span *span);
 static int t4_shutdown(struct dahdi_span *span);
@@ -1089,42 +1116,83 @@
 	return unit;
 }
 
-static int t4_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 t4 *wc = chan->pvt;
+	struct t4_span *tspan = chan->span->pvt;
 	int channel;
-	int unit;
-	
+	const struct dahdi_echocan_ops *ops;
+	const struct dahdi_echocan_features *features;
+
 	if (!wc->vpm)
 		return -ENODEV;
 
 	if (chan->span->offset >= vpmspans)
 		return -ENODEV;
 
-	if (wc->t1e1)
-		channel = chan->chanpos;
-	else
-		channel = chan->chanpos + 4;
+	if (wc->vpm450m) {
+		ops = &vpm450m_ec_ops;
+		features = &vpm450m_ec_features;
+	} else {
+		ops = &vpm400m_ec_ops;
+		features = &vpm400m_ec_features;
+	}
+
+	if (ecp->param_count > 0) {
+		printk(KERN_WARNING "%s echo canceller does not support parameters; failing request\n", ops->name);
+		return -EINVAL;
+	}
+
+	*ec = tspan->ec[chan->chanpos - 1];
+	(*ec)->ops = ops;
+	(*ec)->features = *features;
+
+	channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
+
 	if (wc->vpm450m) {
 		channel = channel << 2;
 		channel |= chan->span->offset;
-		if(debug & DEBUG_ECHOCAN) 
+		if (debug & DEBUG_ECHOCAN) 
 			printk(KERN_DEBUG "echocan: Card is %d, Channel is %d, Span is %d, offset is %d length %d\n", 
-				wc->num, chan->chanpos, chan->span->offset, channel, eclen);
-		vpm450m_setec(wc->vpm450m, channel, eclen);
-// Mark		msleep(10);
-//		msleep(100); // longer test
+			       wc->num, chan->chanpos, chan->span->offset, channel, ecp->tap_length);
+		vpm450m_setec(wc->vpm450m, channel, ecp->tap_length);
 	} else {
-		unit = t4_vpm_unit(chan->span->offset, channel);
-		if(debug & DEBUG_ECHOCAN) 
+		int unit = t4_vpm_unit(chan->span->offset, channel);
+
+		if (debug & DEBUG_ECHOCAN) 
 			printk(KERN_DEBUG "echocan: Card is %d, Channel is %d, Span is %d, unit is %d, unit offset is %d length %d\n", 
-				wc->num, chan->chanpos, chan->span->offset, unit, channel, eclen);
-		if (eclen)
-			t4_vpm_out(wc,unit,channel,0x3e);
-		else
-			t4_vpm_out(wc,unit,channel,0x01);
-	}
+			       wc->num, chan->chanpos, chan->span->offset, unit, channel, ecp->tap_length);
+		t4_vpm_out(wc, unit, channel, 0x3e);
+	}
+
 	return 0;
+}
+
+static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
+{
+	struct t4 *wc = chan->pvt;
+	int channel;
+
+	memset(ec, 0, sizeof(*ec));
+
+	channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
+
+	if (wc->vpm450m) {
+		channel = channel << 2;
+		channel |= chan->span->offset;
+		if (debug & DEBUG_ECHOCAN) 
+			printk(KERN_DEBUG "echocan: Card is %d, Channel is %d, Span is %d, offset is %d length 0\n", 
+			       wc->num, chan->chanpos, chan->span->offset, channel);
+		vpm450m_setec(wc->vpm450m, channel, 0);
+	} else {
+		int unit = t4_vpm_unit(chan->span->offset, channel);
+
+		if (debug & DEBUG_ECHOCAN) 
+			printk(KERN_DEBUG "echocan: Card is %d, Channel is %d, Span is %d, unit is %d, unit offset is %d length 0\n", 
+			       wc->num, chan->chanpos, chan->span->offset, unit, channel);
+		t4_vpm_out(wc, unit, channel, 0x01);
+	}
 }
 #endif
 
@@ -1593,7 +1661,7 @@
 		ts->span.hdlc_hard_xmit = t4_hdlc_hard_xmit;
 		if (gen2) {
 #ifdef VPM_SUPPORT
-			ts->span.echocan = t4_echocan;
+			ts->span.echocan_create = echocan_create;
 #endif			
 			ts->span.dacs = t4_dacs;
 		}
@@ -3494,6 +3562,8 @@
 			if (wc->tspans[x]->chans[y]) {
 				kfree(wc->tspans[x]->chans[y]);
 			}
+			if (wc->tspans[x]->ec[y])
+				kfree(wc->tspans[x]->ec[y]);
 		}
 		kfree(wc->tspans[x]);
 	}
@@ -3630,6 +3700,11 @@
 				return -ENOMEM;
 			}
 			memset(wc->tspans[x]->chans[f], 0, sizeof(*wc->tspans[x]->chans[f]));
+			if (!(wc->tspans[x]->ec[f] = kmalloc(sizeof(*wc->tspans[x]->ec[f]), GFP_KERNEL))) {
+				free_wc(wc);
+				return -ENOMEM;
+			}
+			memset(wc->tspans[x]->ec[f], 0, sizeof(*wc->tspans[x]->ec[f]));
 		}
 
 #ifdef ENABLE_WORKQUEUES

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/wctdm24xxp/base.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=6494&r1=6493&r2=6494
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/wctdm24xxp/base.c Mon Apr 27 09:30:26 2009
@@ -232,6 +232,32 @@
 static int vpmnlpthresh = 24;
 /* See vpmnlptype = 4 for more info */
 static int vpmnlpmaxsupp = 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 vpm100m_ec_features = {
+	.NLP_automatic = 1,
+	.CED_tx_detect = 1,
+	.CED_rx_detect = 1,
+};
+
+static const struct dahdi_echocan_features vpm150m_ec_features = {
+	.NLP_automatic = 1,
+	.CED_tx_detect = 1,
+	.CED_rx_detect = 1,
+};
+
+static const struct dahdi_echocan_ops vpm100m_ec_ops = {
+	.name = "VPM100M",
+	.echocan_free = echocan_free,
+};
+
+static const struct dahdi_echocan_ops vpm150m_ec_ops = {
+	.name = "VPM150M",
+	.echocan_free = echocan_free,
+};
 #endif
 
 static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane);
@@ -1488,9 +1514,40 @@
 
 #include "adt_lec.c"
 
-static int wctdm_echocan_with_params(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
+static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
+			  struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
 {
 	struct wctdm *wc = chan->pvt;
+	const struct dahdi_echocan_ops *ops;
+	const struct dahdi_echocan_features *features;
+
+	if (!wc->vpm
+#ifdef VPM150M_SUPPORT
+	    && !wc->vpm150m
+#endif
+	   )
+		return -ENODEV;
+
+#ifdef VPM150M_SUPPORT
+	if (wc->vpm150m) {
+		ops = &vpm150m_ec_ops;
+		features = &vpm150m_ec_features;
+	} else {
+#endif
+		ops = &vpm100m_ec_ops;
+		features = &vpm100m_ec_features;
+#ifdef VPM150M_SUPPORT
+	}
+#endif
+
+	if (ecp->param_count > 0) {
+		printk(KERN_WARNING "%s echo canceller does not support parameters; failing request\n", ops->name);
+		return -EINVAL;
+	}
+
+	*ec = wc->ec[chan->chanpos - 1];
+	(*ec)->ops = ops;
+	(*ec)->features = *features;
 
 	if (wc->vpm) {
 		int channel;
@@ -1501,15 +1558,10 @@
 		if (wc->vpm < 2)
 			channel >>= 2;
 	
-		if(debug & DEBUG_ECHOCAN) 
+		if (debug & DEBUG_ECHOCAN) 
 			printk(KERN_DEBUG "echocan: Unit is %d, Channel is  %d length %d\n", 
-				unit, channel, ecp->tap_length);
-		if (ecp->tap_length)
-			wctdm_vpm_out(wc,unit,channel,0x3e);
-		else
-			wctdm_vpm_out(wc,unit,channel,0x01);
-
-		return 0;
+			       unit, channel, ecp->tap_length);
+		wctdm_vpm_out(wc, unit, channel, 0x3e);
 #ifdef VPM150M_SUPPORT
 	} else if (wc->vpm150m) {
 		struct vpm150m *vpm150m = wc->vpm150m;

[... 199 lines stripped ...]



More information about the svn-commits mailing list