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

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Apr 13 11:32:29 CDT 2009


Author: kpfleming
Date: Mon Apr 13 11:32:26 2009
New Revision: 6355

URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=6355
Log:
create a branch to hold my echocan interface redesign work


Added:
    linux/team/kpfleming/echocan_work/
      - copied from r6354, linux/trunk/
Modified:
    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_sec.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/dahdi_echocan_hpec.c
    linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/hpec.h
    linux/team/kpfleming/echocan_work/include/dahdi/kernel.h

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=6355&r1=6354&r2=6355
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi-base.c (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/dahdi-base.c Mon Apr 13 11:32:26 2009
@@ -377,62 +377,62 @@
 #define NUM_SIGS	10
 
 #ifdef DEFINE_RWLOCK
-static DEFINE_RWLOCK(echocan_list_lock);
+static DEFINE_RWLOCK(ecfactory_list_lock);
 #else
-static rwlock_t echocan_list_lock = RW_LOCK_UNLOCKED;
-#endif
-
-static LIST_HEAD(echocan_list);
-
-struct echocan {
-	const struct dahdi_echocan *ec;
+static rwlock_t ecfactory_list_lock = RW_LOCK_UNLOCKED;
+#endif
+
+static LIST_HEAD(ecfactory_list);
+
+struct ecfactory {
+	const struct dahdi_echocan_factory *ec;
 	struct module *owner;
 	struct list_head list;
 };
 
-int dahdi_register_echocan(const struct dahdi_echocan *ec)
-{
-	struct echocan *cur;
-
-	write_lock(&echocan_list_lock);
+int dahdi_register_echocan(const struct dahdi_echocan_factory *ec)
+{
+	struct ecfactory *cur;
+
+	write_lock(&ecfactory_list_lock);
 
 	/* make sure it isn't already registered */
-	list_for_each_entry(cur, &echocan_list, list) {
+	list_for_each_entry(cur, &ecfactory_list, list) {
 		if (cur->ec == ec) {
-			write_unlock(&echocan_list_lock);
+			write_unlock(&ecfactory_list_lock);
 			return -EPERM;
 		}
 	}
 
 	if (!(cur = kzalloc(sizeof(*cur), GFP_KERNEL))) {
-		write_unlock(&echocan_list_lock);
+		write_unlock(&ecfactory_list_lock);
 		return -ENOMEM;
 	}
 
 	cur->ec = ec;
 	INIT_LIST_HEAD(&cur->list);
 
-	list_add_tail(&cur->list, &echocan_list);
-
-	write_unlock(&echocan_list_lock);
+	list_add_tail(&cur->list, &ecfactory_list);
+
+	write_unlock(&ecfactory_list_lock);
 
 	return 0;
 }
 
-void dahdi_unregister_echocan(const struct dahdi_echocan *ec)
-{
-	struct echocan *cur, *next;
-
-	write_lock(&echocan_list_lock);
-
-	list_for_each_entry_safe(cur, next, &echocan_list, list) {
+void dahdi_unregister_echocan(const struct dahdi_echocan_factory *ec)
+{
+	struct ecfactory *cur, *next;
+
+	write_lock(&ecfactory_list_lock);
+
+	list_for_each_entry_safe(cur, next, &ecfactory_list, list) {
 		if (cur->ec == ec) {
 			list_del(&cur->list);
 			break;
 		}
 	}
 
-	write_unlock(&echocan_list_lock);
+	write_unlock(&ecfactory_list_lock);
 }
 
 static inline void rotate_sums(void)
@@ -1098,9 +1098,9 @@
 	return ret;
 }
 
-static const struct dahdi_echocan *find_echocan(const char *name)
-{
-	struct echocan *cur;
+static const struct dahdi_echocan_factory *find_echocan(const char *name)
+{
+	struct ecfactory *cur;
 	char name_upper[strlen(name) + 1];
 	char *c;
 	const char *d;
@@ -1114,26 +1114,26 @@
 	*c = '\0';
 
 retry:
-	read_lock(&echocan_list_lock);
-
-	list_for_each_entry(cur, &echocan_list, list) {
+	read_lock(&ecfactory_list_lock);
+
+	list_for_each_entry(cur, &ecfactory_list, list) {
 		if (!strcmp(name_upper, cur->ec->name)) {
 #ifdef USE_ECHOCAN_REFCOUNT
 			if (try_module_get(cur->owner)) {
-				read_unlock(&echocan_list_lock);
+				read_unlock(&ecfactory_list_lock);
 				return cur->ec;
 			} else {
-				read_unlock(&echocan_list_lock);
+				read_unlock(&ecfactory_list_lock);
 				return NULL;
 			}
 #else
-			read_unlock(&echocan_list_lock);
+			read_unlock(&ecfactory_list_lock);
 			return cur->ec;
 #endif
 		}
 	}
 
-	read_unlock(&echocan_list_lock);
+	read_unlock(&ecfactory_list_lock);
 
 	if (tried_once) {
 		return NULL;
@@ -1153,7 +1153,7 @@
 	goto retry;
 }
 
-static void release_echocan(const struct dahdi_echocan *ec)
+static void release_echocan(const struct dahdi_echocan_factory *ec)
 {
 #ifdef USE_ECHOCAN_REFCOUNT
 	module_put(ec->owner);
@@ -1172,8 +1172,8 @@
 {
 	unsigned long flags;
 	void *rxgain = NULL;
-	struct echo_can_state *ec_state;
-	const struct dahdi_echocan *ec_current;
+	struct dahdi_echocan_state *ec_state;
+	const struct dahdi_echocan_factory *ec_current;
 	int oldconf;
 	short *readchunkpreec;
 #ifdef CONFIG_DAHDI_PPP
@@ -1251,7 +1251,7 @@
 		chan->span->dacs(chan, NULL);
 
 	if (ec_state) {
-		ec_current->echo_can_free(ec_state);
+		ec_state->owner->echocan_free(ec_state);
 		release_echocan(ec_current);
 	}
 
@@ -2448,8 +2448,8 @@
 	int res;
 	unsigned long flags;
 	void *rxgain=NULL;
-	struct echo_can_state *ec_state;
-	const struct dahdi_echocan *ec_current;
+	struct dahdi_echocan_state *ec_state;
+	const struct dahdi_echocan_factory *ec_current;
 
 	if ((res = dahdi_reallocbufs(chan, DAHDI_DEFAULT_BLOCKSIZE, DAHDI_DEFAULT_NUM_BUFS)))
 		return res;
@@ -2561,7 +2561,7 @@
 	}
 
 	if (ec_state) {
-		ec_current->echo_can_free(ec_state);
+		ec_state->owner->echocan_free(ec_state);
 		release_echocan(ec_current);
 	}
 
@@ -3850,7 +3850,7 @@
 	case DAHDI_ATTACH_ECHOCAN:
 	{
 		struct dahdi_attach_echocan ae;
-		const struct dahdi_echocan *new = NULL, *old;
+		const struct dahdi_echocan_factory *new = NULL, *old;
 
 		if (copy_from_user(&ae, (struct dahdi_attach_echocan *) data, sizeof(ae))) {
 			return -EFAULT;
@@ -4171,19 +4171,19 @@
 	case DAHDI_GETVERSION:
 	{
 		struct dahdi_versioninfo vi;
-		struct echocan *cur;
+		struct ecfactory *cur;
 		size_t space = sizeof(vi.echo_canceller) - 1;
 
 		memset(&vi, 0, sizeof(vi));
 		dahdi_copy_string(vi.version, DAHDI_VERSION, sizeof(vi.version));
-		read_lock(&echocan_list_lock);
-		list_for_each_entry(cur, &echocan_list, list) {
+		read_lock(&ecfactory_list_lock);
+		list_for_each_entry(cur, &ecfactory_list, list) {
 			strncat(vi.echo_canceller + strlen(vi.echo_canceller), cur->ec->name, space);
 			space -= strlen(cur->ec->name);
 			if (space < 1) {
 				break;
 			}
-			if (cur->list.next && (cur->list.next != &echocan_list)) {
+			if (cur->list.next && (cur->list.next != &ecfactory_list)) {
 				strncat(vi.echo_canceller + strlen(vi.echo_canceller), ", ", space);
 				space -= 2;
 				if (space < 1) {
@@ -4191,7 +4191,7 @@
 				}
 			}
 		}
-		read_unlock(&echocan_list_lock);
+		read_unlock(&ecfactory_list_lock);
 		if (copy_to_user((struct dahdi_versioninfo *) data, &vi, sizeof(vi)))
 			return -EFAULT;
 		break;
@@ -4853,8 +4853,8 @@
 
 static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, void *data)
 {
-	struct echo_can_state *ec = NULL, *ec_state;
-	const struct dahdi_echocan *ec_current;
+	struct dahdi_echocan_state *ec = NULL, *ec_state;
+	const struct dahdi_echocan_factory *ec_current;
 	struct dahdi_echocanparam *params;
 	int ret;
 	unsigned long flags;
@@ -4875,7 +4875,7 @@
 		chan->echotimer = 0;
 		spin_unlock_irqrestore(&chan->lock, flags);
 		if (ec_state) {
-			ec_current->echo_can_free(ec_state);
+			ec_state->owner->echocan_free(ec_state);
 			release_echocan(ec_current);
 		}
 		hw_echocancel_off(chan);
@@ -4908,7 +4908,7 @@
 	chan->ec_current = NULL;
 	spin_unlock_irqrestore(&chan->lock, flags);
 	if (ec_state) {
-		ec_current->echo_can_free(ec_state);
+		ec_state->owner->echocan_free(ec_state);
 		release_echocan(ec_current);
 	}
 
@@ -4949,7 +4949,7 @@
 		   an echo canceler instance if possible */
 		ec_current = chan->ec_factory;
 
-		if ((ret = ec_current->echo_can_create(ecp, params, &ec))) {
+		if ((ret = ec_current->echocan_create(ecp, params, &ec))) {
 			release_echocan(ec_current);
 
 			goto exit_with_free;
@@ -4962,8 +4962,8 @@
 		chan->echostate = ECHO_STATE_IDLE;
 		chan->echolastupdate = 0;
 		chan->echotimer = 0;
-		echo_can_disable_detector_init(&chan->txecdis);
-		echo_can_disable_detector_init(&chan->rxecdis);
+		echo_can_disable_detector_init(&chan->ec_state->txecdis);
+		echo_can_disable_detector_init(&chan->ec_state->rxecdis);
 		spin_unlock_irqrestore(&chan->lock, flags);
 	}
 
@@ -5019,8 +5019,8 @@
 			/* Coming out of audio mode, also clear all
 			   conferencing and gain related info as well
 			   as echo canceller */
-			struct echo_can_state *ec_state;
-			const struct dahdi_echocan *ec_current;
+			struct dahdi_echocan_state *ec_state;
+			const struct dahdi_echocan_factory *ec_current;
 
 			spin_lock_irqsave(&chan->lock, flags);
 			chan->flags &= ~DAHDI_FLAG_AUDIO;
@@ -5053,7 +5053,7 @@
 			spin_unlock_irqrestore(&chan->lock, flags);
 
 			if (ec_state) {
-				ec_current->echo_can_free(ec_state);
+				ec_state->owner->echocan_free(ec_state);
 				release_echocan(ec_current);
 			}
 
@@ -5073,8 +5073,8 @@
 			if (!chan->ppp) {
 				chan->ppp = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL);
 				if (chan->ppp) {
-					struct echo_can_state *tec;
-					const struct dahdi_echocan *ec_current;
+					struct dahdi_echocan_state *tec;
+					const struct dahdi_echocan_factory *ec_current;
 
 					chan->ppp->private = chan;
 					chan->ppp->ops = &ztppp_ops;
@@ -5114,7 +5114,7 @@
 					hw_echocancel_off(chan);
 
 					if (tec) {
-						ec_current->echo_can_free(tec);
+						tec->owner->echocan_free(tec);
 						release_echocan(ec_current);
 					}
 				} else
@@ -5744,13 +5744,13 @@
 	if (ms->ec_state) {
 		for (x=0;x<DAHDI_CHUNKSIZE;x++) {
 			/* Check for echo cancel disabling tone */
-			if (echo_can_disable_detector_update(&ms->txecdis, getlin[x])) {
+			if (echo_can_disable_detector_update(&ms->ec_state->txecdis, getlin[x])) {
 				module_printk(KERN_NOTICE, "Disabled echo canceller because of tone (tx) on channel %d\n", ss->channo);
 				ms->echocancel = 0;
 				ms->echostate = ECHO_STATE_IDLE;
 				ms->echolastupdate = 0;
 				ms->echotimer = 0;
-				ms->ec_current->echo_can_free(ms->ec_state);
+				ms->ec_state->owner->echocan_free(ms->ec_state);
 				ms->ec_state = NULL;
 				release_echocan(ms->ec_current);
 				ms->ec_current = NULL;
@@ -6580,7 +6580,7 @@
 					ss->echostate = ECHO_STATE_TRAINING;
 				}
 				if (ss->echostate == ECHO_STATE_TRAINING) {
-					if (ss->ec_current->echo_can_traintap(ss->ec_state, ss->echolastupdate++, rxlin)) {
+					if (ss->ec_state->owner->echocan_traintap(ss->ec_state, ss->echolastupdate++, rxlin)) {
 #if 0
 						module_printk(KERN_NOTICE, "Finished training (%d taps trained)!\n", ss->echolastupdate);
 #endif
@@ -6596,7 +6596,7 @@
 				rxlins[x] = DAHDI_XLAW(rxchunk[x], ss);
 				txlins[x] = DAHDI_XLAW(txchunk[x], ss);
 			}
-			ss->ec_current->echo_can_array_update(ss->ec_state, rxlins, txlins);
+			ss->ec_state->owner->echocan_array_update(ss->ec_state, rxlins, txlins);
 			for (x = 0; x < DAHDI_CHUNKSIZE; x++)
 				rxchunk[x] = DAHDI_LIN2X((int) rxlins[x], ss);
 		}
@@ -6694,13 +6694,13 @@
 #ifndef NO_ECHOCAN_DISABLE
 	if (ms->ec_state) {
 		for (x=0;x<DAHDI_CHUNKSIZE;x++) {
-			if (echo_can_disable_detector_update(&ms->rxecdis, putlin[x])) {
+			if (echo_can_disable_detector_update(&ms->ec_state->rxecdis, putlin[x])) {
 				module_printk(KERN_NOTICE, "Disabled echo canceller because of tone (rx) on channel %d\n", ss->channo);
 				ms->echocancel = 0;
 				ms->echostate = ECHO_STATE_IDLE;
 				ms->echolastupdate = 0;
 				ms->echotimer = 0;
-				ms->ec_current->echo_can_free(ms->ec_state);
+				ms->ec_state->owner->echocan_free(ms->ec_state);
 				ms->ec_state = NULL;
 				release_echocan(ms->ec_current);
 				ms->ec_current = NULL;

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=6355&r1=6354&r2=6355
==============================================================================
--- 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 13 11:32:26 2009
@@ -40,84 +40,98 @@
 #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)
 
-struct echo_can_state {
+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, short *iref);
+static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
+
+static const struct dahdi_echocan_factory my_factory = {
+	.name = "JPAH",
+	.owner = THIS_MODULE,
+	.echocan_create = echo_can_create,
+};
+
+static const struct dahdi_echocan me = {
+	.echocan_free = echo_can_free,
+	.echocan_array_update = echo_can_array_update,
+	.echocan_traintap = echo_can_traintap,
+};
+
+struct ec_pvt {
+	struct dahdi_echocan_state dahdi;
 	int blah;
 };
 
+#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 echo_can_state **ec)
+			   struct dahdi_echocan_state **ec)
 {
-	unsigned int x;
-	char *c;
+	struct ec_pvt *pvt;
 
-	if ((*ec = kmalloc(sizeof(**ec), GFP_KERNEL))) {
-		memset(ec, 0, sizeof(**ec));
-	}
-
-	for (x = 0; x < ecp->param_count; x++) {
-		for (c = p[x].name; *c; c++)
-			*c = tolower(*c);
-		printk(KERN_WARNING "Unknown parameter supplied to JPAH echo canceler: '%s'\n", p[x].name);
-		kfree(*ec);
-
+	if (ecp->param_count > 0) {
+		printk(KERN_WARNING "JPAH does not support parameters; failing request\n");
 		return -EINVAL;
 	}
 
+	if (!(pvt = kmalloc(sizeof(*pvt), GFP_KERNEL))) {
+		return -ENOMEM;
+	}
+
+	memset(&pvt, 0, sizeof(*pvt));
+	pvt->dahdi.owner = &me;
+
+	*ec = &pvt->dahdi;
 	return 0;
 }
 
-static void echo_can_free(struct echo_can_state *ec)
+static void echo_can_free(struct dahdi_echocan_state *ec)
 {
-	kfree(ec);
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
+
+	kfree(pvt);
 }
 
-static void echo_can_update(struct echo_can_state *ec, short *isig, short *iref)
+static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, short *iref)
 {
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 	unsigned int x;
 
 	for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
-		if (ec->blah < 2) {
-			ec->blah++;
+		if (pvt->blah < 2) {
+			pvt->blah++;
 
 			*isig++ = 0;
 		} else {
-			ec->blah = 0;
+			pvt->blah = 0;
 			
 			isig++;
 		}
 	}
 }
 
-static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val)
 {
 	return 0;
 }
 
-static const struct dahdi_echocan me = {
-	.name = "JPAH",
-	.owner = THIS_MODULE,
-	.echo_can_create = echo_can_create,
-	.echo_can_free = echo_can_free,
-	.echo_can_array_update = echo_can_update,
-	.echo_can_traintap = echo_can_traintap,
-};
-
 static int __init mod_init(void)
 {
-	if (dahdi_register_echocan(&me)) {
+	if (dahdi_register_echocan(&my_factory)) {
 		module_printk(KERN_ERR, "could not register with DAHDI core\n");
 
 		return -EPERM;
 	}
 
-	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name);
 
 	return 0;
 }
 
 static void __exit mod_exit(void)
 {
-	dahdi_unregister_echocan(&me);
+	dahdi_unregister_echocan(&my_factory);
 }
 
 module_param(debug, int, S_IRUGO | S_IWUSR);

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=6355&r1=6354&r2=6355
==============================================================================
--- 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 13 11:32:26 2009
@@ -67,35 +67,55 @@
 
 #define NONUPDATE_DWELL_TIME	600 	/* 600 samples, or 75ms */
 
-struct echo_can_state
-{
-    int tx_power;
-    int rx_power;
-    int clean_rx_power;
-
-    int rx_power_threshold;
-    int nonupdate_dwell;
-
-    int16_t *tx_history;	/* Last N tx samples */
-    int32_t *fir_taps;	    	/* Echo FIR taps */
+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, short *iref);
+static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
+
+static const struct dahdi_echocan_factory my_factory = {
+	.name = "SEC",
+	.owner = THIS_MODULE,
+	.echocan_create = echo_can_create,
+};
+
+static const struct dahdi_echocan me = {
+	.echocan_free = echo_can_free,
+	.echocan_array_update = echo_can_array_update,
+	.echocan_traintap = echo_can_traintap,
+};
+
+struct ec_pvt {
+	struct dahdi_echocan_state dahdi;
+	int tx_power;
+	int rx_power;
+	int clean_rx_power;
+
+	int rx_power_threshold;
+	int nonupdate_dwell;
+
+	int16_t *tx_history;	/* Last N tx samples */
+	int32_t *fir_taps;	    	/* Echo FIR taps */
 	int16_t *fir_taps_short;	/* Echo FIR taps, shorts instead of ints */
 
-    int curr_pos;
+	int curr_pos;
+
+	int taps;
+	int tap_mask;
+	int use_nlp;
+	int use_suppressor;
 	
-    int taps;
-    int tap_mask;
-    int use_nlp;
-    int use_suppressor;
-    
-    int32_t supp_test1;
-    int32_t supp_test2;
-    int32_t supp1;
-    int32_t supp2;
-
-    int32_t latest_correction;  /* Indication of the magnitude of the latest
-    				   adaption, or a code to indicate why adaption
-				   was skipped, for test purposes */
+	int32_t supp_test1;
+	int32_t supp_test2;
+	int32_t supp1;
+	int32_t supp2;
+
+	int32_t latest_correction;  /* Indication of the magnitude of the latest
+				       adaption, or a code to indicate why adaption
+				       was skipped, for test purposes */
 };
+
+#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
 
 /* Original parameters : 
 #define MIN_TX_POWER_FOR_ADAPTION   256
@@ -111,54 +131,58 @@
 */
 
 static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct echo_can_state **ec)
-{
+			   struct dahdi_echocan_state **ec)
+{
+	struct ec_pvt *pvt;
 	size_t size;
+
+	if (ecp->param_count > 0) {
+		printk(KERN_WARNING "JPAH does not support parameters; failing request\n");
+		return -EINVAL;
+	}
+
+	size = sizeof(*pvt) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t);
 	
-	if (ecp->param_count > 0) {
-		printk(KERN_WARNING "SEC echo canceler does not support parameters; failing request\n");
-		return -EINVAL;
-	}
-	
-	size = sizeof(**ec) + ecp->tap_length * sizeof(int32_t) + ecp->tap_length * 3 * sizeof(int16_t);
-	
-	if (!(*ec = kmalloc(size, GFP_KERNEL)))
+	if (!(pvt = kmalloc(size, GFP_KERNEL))) {
 		return -ENOMEM;
-	
-	memset(*ec, 0, size);
-
-	(*ec)->taps = ecp->tap_length;
-	(*ec)->tap_mask = ecp->tap_length - 1;
-	(*ec)->tx_history = (int16_t *) (*ec + sizeof(**ec));
-	(*ec)->fir_taps = (int32_t *) (*ec + sizeof(**ec) +
-				       ecp->tap_length * 2 * sizeof(int16_t));
-	(*ec)->fir_taps_short = (int16_t *) (*ec + sizeof(**ec) +
-					     ecp->tap_length * sizeof(int32_t) +
-					     ecp->tap_length * 2 * sizeof(int16_t));
-	(*ec)->rx_power_threshold = 10000000;
-	(*ec)->use_suppressor = FALSE;
+	}
+
+	memset(&pvt, 0, sizeof(*pvt));
+	pvt->dahdi.owner = &me;
+
+	pvt->taps = ecp->tap_length;
+	pvt->tap_mask = ecp->tap_length - 1;
+	pvt->tx_history = (int16_t *) (pvt + sizeof(*pvt));
+	pvt->fir_taps = (int32_t *) (pvt + sizeof(*pvt) +
+				     ecp->tap_length * 2 * sizeof(int16_t));
+	pvt->fir_taps_short = (int16_t *) (pvt + sizeof(*pvt) +
+					   ecp->tap_length * sizeof(int32_t) +
+					   ecp->tap_length * 2 * sizeof(int16_t));
+	pvt->rx_power_threshold = 10000000;
+	pvt->use_suppressor = FALSE;
 	/* Non-linear processor - a fancy way to say "zap small signals, to avoid
 	   accumulating noise". */
-	(*ec)->use_nlp = TRUE;
-
+	pvt->use_nlp = TRUE;
+
+	*ec = &pvt->dahdi;
 	return 0;
 }
-/*- End of function --------------------------------------------------------*/
-
-static void echo_can_free(struct echo_can_state *ec)
-{
-	kfree(ec);
-}
-/*- End of function --------------------------------------------------------*/
-
-static inline int16_t sample_update(struct echo_can_state *ec, int16_t tx, int16_t rx)
+
+static void echo_can_free(struct dahdi_echocan_state *ec)
+{
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
+
+	kfree(pvt);
+}
+
+static inline int16_t sample_update(struct ec_pvt *pvt, int16_t tx, int16_t rx)
 {
     int32_t echo_value;
     int clean_rx;
     int nsuppr;
 
-    ec->tx_history[ec->curr_pos] = tx;
-    ec->tx_history[ec->curr_pos + ec->taps] = tx;
+    pvt->tx_history[pvt->curr_pos] = tx;
+    pvt->tx_history[pvt->curr_pos + pvt->taps] = tx;
 
     /* Evaluate the echo - i.e. apply the FIR filter */
     /* Assume the gain of the FIR does not exceed unity. Exceeding unity
@@ -175,9 +199,9 @@
        bad!), but 32 bit coeffs require some shifting. On balance 32 bit seems
        best */
 #ifdef USE_SHORTS
-    echo_value = CONVOLVE2(ec->fir_taps_short, ec->tx_history + ec->curr_pos, ec->taps);
+    echo_value = CONVOLVE2(pvt->fir_taps_short, pvt->tx_history + pvt->curr_pos, pvt->taps);
 #else
-    echo_value = CONVOLVE(ec->fir_taps, ec->tx_history + ec->curr_pos, ec->taps);
+    echo_value = CONVOLVE(pvt->fir_taps, pvt->tx_history + pvt->curr_pos, pvt->taps);
 #endif
     echo_value >>= 16;
 
@@ -185,8 +209,8 @@
     clean_rx = rx - echo_value;
 
     /* That was the easy part. Now we need to adapt! */
-    if (ec->nonupdate_dwell > 0)
-    	ec->nonupdate_dwell--;
+    if (pvt->nonupdate_dwell > 0)
+    	pvt->nonupdate_dwell--;
 
     /* If there is very little being transmitted, any attempt to train is
        futile. We would either be training on the far end's noise or signal,
@@ -196,20 +220,20 @@
        we are already well adapted. There is little point in trying to improve
        the adaption under these circumstanceson, so don't do it (reduce the
        compute load). */
-    if (ec->tx_power > MIN_TX_POWER_FOR_ADAPTION
+    if (pvt->tx_power > MIN_TX_POWER_FOR_ADAPTION
     	&&
-	ec->rx_power > MIN_RX_POWER_FOR_ADAPTION)
+	pvt->rx_power > MIN_RX_POWER_FOR_ADAPTION)
     {
     	/* This is a really crude piece of decision logic, but it does OK
 	   for now. */
-    	if (ec->tx_power > ec->rx_power << 1)
+    	if (pvt->tx_power > pvt->rx_power << 1)
 	{
             /* There is no far-end speech detected */
-            if (ec->nonupdate_dwell == 0)
+            if (pvt->nonupdate_dwell == 0)
 	    {
 	    	/* ... and we are not in the dwell time from previous speech. */
-		//nsuppr = saturate((clean_rx << 16)/ec->tx_power);
-		nsuppr = (clean_rx << 16) / ec->tx_power;
+		//nsuppr = saturate((clean_rx << 16)/pvt->tx_power);
+		nsuppr = (clean_rx << 16) / pvt->tx_power;
 		nsuppr >>= 4;
 		if (nsuppr > 512)
 			nsuppr = 512;
@@ -217,114 +241,106 @@
 			nsuppr = -512;
 
 		/* Update the FIR taps */
-		ec->latest_correction = 0;
+		pvt->latest_correction = 0;
 #ifdef USE_SHORTS
-		UPDATE2(ec->fir_taps, ec->fir_taps_short, ec->tx_history + ec->curr_pos, nsuppr, ec->taps);
+		UPDATE2(pvt->fir_taps, pvt->fir_taps_short, pvt->tx_history + pvt->curr_pos, nsuppr, pvt->taps);
 #else				
-		UPDATE(ec->fir_taps, ec->fir_taps_short, ec->tx_history + ec->curr_pos, nsuppr, ec->taps);
+		UPDATE(pvt->fir_taps, pvt->fir_taps_short, pvt->tx_history + pvt->curr_pos, nsuppr, pvt->taps);
 #endif		
 	   }  else
 	    {
-        	ec->latest_correction = -3;
+        	pvt->latest_correction = -3;
     	    }
 	}
 	else
 	{
-            ec->nonupdate_dwell = NONUPDATE_DWELL_TIME;
-    	    ec->latest_correction = -2;
+            pvt->nonupdate_dwell = NONUPDATE_DWELL_TIME;
+    	    pvt->latest_correction = -2;
 	}
     }
     else
     {
-        ec->nonupdate_dwell = 0;
-        ec->latest_correction = -1;
+        pvt->nonupdate_dwell = 0;
+        pvt->latest_correction = -1;
     }
     /* Calculate short term power levels using very simple single pole IIRs */
     /* TODO: Is the nasty modulus approach the fastest, or would a real
        tx*tx power calculation actually be faster? */
-    ec->tx_power += ((abs(tx) - ec->tx_power) >> 5);
-    ec->rx_power += ((abs(rx) - ec->rx_power) >> 5);
-    ec->clean_rx_power += ((abs(clean_rx) - ec->clean_rx_power) >> 5);
+    pvt->tx_power += ((abs(tx) - pvt->tx_power) >> 5);
+    pvt->rx_power += ((abs(rx) - pvt->rx_power) >> 5);
+    pvt->clean_rx_power += ((abs(clean_rx) - pvt->clean_rx_power) >> 5);
 
 #if defined(XYZZY)
-    if (ec->use_suppressor)
+    if (pvt->use_suppressor)
     {
-    	ec->supp_test1 += (ec->tx_history[ec->curr_pos] - ec->tx_history[(ec->curr_pos - 7) & ec->tap_mask]);
-    	ec->supp_test2 += (ec->tx_history[(ec->curr_pos - 24) & ec->tap_mask] - ec->tx_history[(ec->curr_pos - 31) & ec->tap_mask]);
-    	if (ec->supp_test1 > 42  &&  ec->supp_test2 > 42)
+    	pvt->supp_test1 += (pvt->tx_history[pvt->curr_pos] - pvt->tx_history[(pvt->curr_pos - 7) & pvt->tap_mask]);
+    	pvt->supp_test2 += (pvt->tx_history[(pvt->curr_pos - 24) & pvt->tap_mask] - pvt->tx_history[(pvt->curr_pos - 31) & pvt->tap_mask]);
+    	if (pvt->supp_test1 > 42  &&  pvt->supp_test2 > 42)
     	    supp_change = 25;
     	else
     	    supp_change = 50;
-    	supp = supp_change + k1*ec->supp1 + k2*ec->supp2;
-	ec->supp2 = ec->supp1;
-	ec->supp1 = supp;
+    	supp = supp_change + k1*pvt->supp1 + k2*pvt->supp2;
+	pvt->supp2 = pvt->supp1;
+	pvt->supp1 = supp;
 	clean_rx *= (1 - supp);
     }
 #endif
 
-    if (ec->use_nlp  &&  ec->rx_power < 32)
+    if (pvt->use_nlp  &&  pvt->rx_power < 32)
     	clean_rx = 0;
 
     /* Roll around the rolling buffer */
-    ec->curr_pos = (ec->curr_pos - 1) & ec->tap_mask;
+    pvt->curr_pos = (pvt->curr_pos - 1) & pvt->tap_mask;
 
     return clean_rx;
 }
-/*- End of function --------------------------------------------------------*/
-
-static void echo_can_update(struct echo_can_state *ec, short *isig, short *iref)
-{
+
+static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, short *iref)
+{
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
 	unsigned int x;
 	short result;
 
 	for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
-		result = sample_update(ec, *iref, *isig);
+		result = sample_update(pvt, *iref, *isig);
 		*isig++ = result;
 		++iref;
 	}
 }
-/*- End of function --------------------------------------------------------*/
-
-static int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
-{
+
+static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val)
+{
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
+
 	/* Reset hang counter to avoid adjustments after
 	   initial forced training */
-	ec->nonupdate_dwell = ec->taps << 1;
-	if (pos >= ec->taps)
+	pvt->nonupdate_dwell = pvt->taps << 1;
+	if (pos >= pvt->taps)
 		return 1;
-	ec->fir_taps[pos] = val << 17;
-	ec->fir_taps_short[pos] = val << 1;
-	if (++pos >= ec->taps)
+	pvt->fir_taps[pos] = val << 17;
+	pvt->fir_taps_short[pos] = val << 1;
+	if (++pos >= pvt->taps)
 		return 1;
+	else
+		return 0;
+}
+
+static int __init mod_init(void)
+{
+	if (dahdi_register_echocan(&my_factory)) {
+		module_printk(KERN_ERR, "could not register with DAHDI core\n");
+
+		return -EPERM;
+	}
+
+	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name);
+
 	return 0;
 }
-/*- End of function --------------------------------------------------------*/
-
-static const struct dahdi_echocan me = {
-	.name = "SEC",
-	.owner = THIS_MODULE,
-	.echo_can_create = echo_can_create,
-	.echo_can_free = echo_can_free,
-	.echo_can_array_update = echo_can_update,
-	.echo_can_traintap = echo_can_traintap,
-};
-
-static int __init mod_init(void)
-{
-	if (dahdi_register_echocan(&me)) {
-		module_printk(KERN_ERR, "could not register with DAHDI core\n");
-
-		return -EPERM;
-	}
-
-	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
-
-	return 0;
-}
 
 static void __exit mod_exit(void)
 {
-	dahdi_unregister_echocan(&me);
+	dahdi_unregister_echocan(&my_factory);
 }
 
 module_param(debug, int, S_IRUGO | S_IWUSR);

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=6355&r1=6354&r2=6355
==============================================================================
--- 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 13 11:32:26 2009
@@ -36,7 +36,32 @@
 #include "hpec_user.h"
 #include "hpec.h"
 
-static int __attribute__((regparm(0))) __attribute__((format (printf, 1, 2))) logger(const char *format, ...)
+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, short *iref);
+static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val);
+
+static const struct dahdi_echocan_factory my_factory = {
+	.name = "HPEC",
+	.owner = THIS_MODULE,
+	.echocan_create = echo_can_create,
+};
+
+static const struct dahdi_echocan me = {
+	.echocan_free = echo_can_free,
+	.echocan_array_update = echo_can_array_update,
+	.echocan_traintap = echo_can_traintap,
+};
+
+struct ec_pvt {
+	struct hpec_state *hpec;
+	struct dahdi_echocan_state dahdi;
+};
+
+#define dahdi_to_pvt(a) container_of(a, struct ec_pvt, dahdi)
+
+static int __attribute__((regparm(0), format(printf, 1, 2))) logger(const char *format, ...)
 {
 	int res;
 	va_list args;
@@ -67,37 +92,58 @@
 	kfree(ptr);
 }
 
-static void echo_can_free(struct echo_can_state *ec)
-{
-	hpec_channel_free(ec);
-}
-
-static void echo_can_array_update(struct echo_can_state *ec, short *isig, short *iref)
-{
-	hpec_channel_update(ec, isig, iref);
+static void echo_can_free(struct dahdi_echocan_state *ec)
+{
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
+
+	hpec_channel_free(pvt->hpec);
+	kfree(pvt);
+}
+
+static void echo_can_array_update(struct dahdi_echocan_state *ec, short *isig, short *iref)
+{
+	struct ec_pvt *pvt = dahdi_to_pvt(ec);
+
+	hpec_channel_update(pvt->hpec, isig, iref);
 }
 
 DECLARE_MUTEX(alloc_lock);
 
 static int echo_can_create(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p,
-			   struct echo_can_state **ec)
-{
+			   struct dahdi_echocan_state **ec)
+{
+	struct ec_pvt *pvt;
+
 	if (ecp->param_count > 0) {
 		printk(KERN_WARNING "HPEC does not support parameters; failing request\n");
 		return -EINVAL;
 	}
 
+	if (!(pvt = kmalloc(sizeof(*pvt), GFP_KERNEL))) {
+		return -ENOMEM;
+	}
+
+	memset(&pvt, 0, sizeof(*pvt));
+	pvt->dahdi.owner = &me;
+
 	if (down_interruptible(&alloc_lock))
 		return -ENOTTY;
 
-	*ec = hpec_channel_alloc(ecp->tap_length);
+	pvt->hpec = hpec_channel_alloc(ecp->tap_length);
 
 	up(&alloc_lock);
 
-	return *ec ? 0 : -ENOTTY;
-}
-
-static inline int echo_can_traintap(struct echo_can_state *ec, int pos, short val)
+	if (!pvt->hpec) {
+		kfree(pvt);
+		*ec = NULL;
+		return -ENOTTY;
+	} else {
+		*ec = &pvt->dahdi;
+		return 0;
+	}
+}
+
+static int echo_can_traintap(struct dahdi_echocan_state *ec, int pos, short val)
 {
 	return 1;
 }
@@ -135,24 +181,15 @@
 	}
 }
 
-static const struct dahdi_echocan me = {
-	.name = "HPEC",
-	.owner = THIS_MODULE,
-	.echo_can_create = echo_can_create,
-	.echo_can_free = echo_can_free,
-	.echo_can_array_update = echo_can_array_update,
-	.echo_can_traintap = echo_can_traintap,
-};
-
 static int __init mod_init(void)
 {
-	if (dahdi_register_echocan(&me)) {
+	if (dahdi_register_echocan(&my_factory)) {
 		module_printk(KERN_ERR, "could not register with DAHDI core\n");
 
 		return -EPERM;
 	}
 
-	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", me.name);
+	module_printk(KERN_NOTICE, "Registered echo canceler '%s'\n", my_factory.name);
 
 	hpec_init(logger, debug, DAHDI_CHUNKSIZE, memalloc, memfree);
 
@@ -163,7 +200,7 @@
 
 static void __exit mod_exit(void)
 {
-	dahdi_unregister_echocan(&me);
+	dahdi_unregister_echocan(&my_factory);
 
 	dahdi_set_hpec_ioctl(NULL);
 

Modified: linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/hpec.h
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/hpec.h?view=diff&rev=6355&r1=6354&r2=6355
==============================================================================
--- linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/hpec.h (original)
+++ linux/team/kpfleming/echocan_work/drivers/dahdi/hpec/hpec.h Mon Apr 13 11:32:26 2009
@@ -22,9 +22,9 @@
 #if !defined(_HPEC_H)
 #define _HPEC_H
 
-struct echo_can_state;
+struct hpec_state;
 
-void __attribute__((regparm(0))) hpec_init(int __attribute__((regparm(0))) __attribute__((format (printf, 1, 2))) (*logger)(const char *format, ...),
+void __attribute__((regparm(0))) hpec_init(int __attribute__((regparm(0), format(printf, 1, 2))) (*logger)(const char *format, ...),
 					   unsigned int debug,
 					   unsigned int chunk_size,
 					   void * (*memalloc)(size_t len),
@@ -36,11 +36,11 @@
 
 int __attribute__((regparm(0))) hpec_license_check(struct hpec_license *license);
 
-struct echo_can_state __attribute__((regparm(0))) *hpec_channel_alloc(unsigned int len);
+struct hpec_state __attribute__((regparm(0))) *hpec_channel_alloc(unsigned int len);
 
-void __attribute__((regparm(0))) hpec_channel_free(struct echo_can_state *channel);
+void __attribute__((regparm(0))) hpec_channel_free(struct hpec_state *channel);
 
-void __attribute__((regparm(0))) hpec_channel_update(struct echo_can_state *channel, short *isig, short *iref);
+void __attribute__((regparm(0))) hpec_channel_update(struct hpec_state *channel, short *isig, short *iref);
 
 #endif /* !defined(_HPEC_H) */
 

Modified: linux/team/kpfleming/echocan_work/include/dahdi/kernel.h
URL: http://svn.digium.com/svn-view/dahdi/linux/team/kpfleming/echocan_work/include/dahdi/kernel.h?view=diff&rev=6355&r1=6354&r2=6355
==============================================================================
--- linux/team/kpfleming/echocan_work/include/dahdi/kernel.h (original)
+++ linux/team/kpfleming/echocan_work/include/dahdi/kernel.h Mon Apr 13 11:32:26 2009
@@ -147,6 +147,31 @@
 	int inbuf;
 	int outbuf;
 };
+
+struct dahdi_echocan_state;
+
+struct dahdi_echocan {
+	void (*echocan_free)(struct dahdi_echocan_state *ec);
+	void (*echocan_array_update)(struct dahdi_echocan_state *ec, short *isig, short *iref);
+	int (*echocan_traintap)(struct dahdi_echocan_state *ec, int pos, short val);
+};
+
+struct dahdi_echocan_state {
+	const struct dahdi_echocan *owner;
+	echo_can_disable_detector_state_t txecdis;
+	echo_can_disable_detector_state_t rxecdis;
+};
+
+/* Echo cancellation factories (modules) */
+
+struct dahdi_echocan_factory {
+	const char *name;
+	struct module *owner;
+	int (*echocan_create)(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
+};
+
+int dahdi_register_echocan(const struct dahdi_echocan_factory *ec);
+void dahdi_unregister_echocan(const struct dahdi_echocan_factory *ec);
 
 struct dahdi_chan {
 #ifdef CONFIG_DAHDI_NET
@@ -299,15 +324,13 @@
 	int		echocancel;
 	/*! The echo canceler module that should be used to create an
 	   instance when this channel needs one */
-	const struct dahdi_echocan *ec_factory;
+	const struct dahdi_echocan_factory *ec_factory;
 	/*! The echo canceler module that owns the instance currently
 	   on this channel, if one is present */
-	const struct dahdi_echocan *ec_current;
-	/*! The private state data of the echo canceler instance in use */
-	struct echo_can_state *ec_state;
-	echo_can_disable_detector_state_t txecdis;
-	echo_can_disable_detector_state_t rxecdis;
-	
+	const struct dahdi_echocan_factory *ec_current;
+	/*! The state data of the echo canceler instance in use */
+	struct dahdi_echocan_state *ec_state;
+
 	int		echostate;		/*!< State of echo canceller */
 	int		echolastupdate;		/*!< Last echo can update pos */
 	int		echotimer;		/*!< Timer for echo update */
@@ -373,21 +396,6 @@
 	struct dahdi_chan *chan;
 };
 #endif
-
-/* Echo cancellation */
-struct echo_can_state;
-
-struct dahdi_echocan {
-	const char *name;
-	struct module *owner;
-	int (*echo_can_create)(struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p, struct echo_can_state **ec);
-	void (*echo_can_free)(struct echo_can_state *ec);
-	void (*echo_can_array_update)(struct echo_can_state *ec, short *isig, short *iref);
-	int (*echo_can_traintap)(struct echo_can_state *ec, int pos, short val);
-};
-
-int dahdi_register_echocan(const struct dahdi_echocan *ec);
-void dahdi_unregister_echocan(const struct dahdi_echocan *ec);
 
 /*! Define the maximum block size */
 #define DAHDI_MAX_BLOCKSIZE	8192




More information about the svn-commits mailing list