diff options
Diffstat (limited to 'drivers/dahdi/wcte12xp/vpmadt032.c')
-rw-r--r-- | drivers/dahdi/wcte12xp/vpmadt032.c | 1317 |
1 files changed, 0 insertions, 1317 deletions
diff --git a/drivers/dahdi/wcte12xp/vpmadt032.c b/drivers/dahdi/wcte12xp/vpmadt032.c deleted file mode 100644 index 2424f67..0000000 --- a/drivers/dahdi/wcte12xp/vpmadt032.c +++ /dev/null @@ -1,1317 +0,0 @@ -/* - * Digium, Inc. Wildcard TE12xP T1/E1 card Driver - * - * Written by Michael Spiceland <mspiceland@digium.com> - * - * Adapted from the wctdm24xxp and wcte11xp drivers originally - * written by Mark Spencer <markster@digium.com> - * Matthew Fredrickson <creslin@digium.com> - * William Meadows <wmeadows@digium.com> - * - * Copyright (C) 2007, Digium, Inc. - * - * All rights reserved. - * - */ - -/* - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2 as published by the - * Free Software Foundation. See the LICENSE file included with - * this program for more details. - */ - -#include <linux/delay.h> -#include <linux/version.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#include <linux/semaphore.h> -#else -#include <asm/semaphore.h> -#endif -#include <linux/pci.h> -#include <linux/firmware.h> -#include <linux/list.h> - -#include <dahdi/kernel.h> - -#include "voicebus.h" - -#include "wcte12xp.h" -#include "vpmadt032.h" -#include "GpakApi.h" - -#ifdef VPM_SUPPORT - -inline void vpm150m_cmd_dequeue(struct t1 *wc, volatile unsigned char *writechunk, int whichframe) -{ - struct vpm150m_cmd *curcmd = NULL; - struct vpm150m *vpm150m = wc->vpm150m; - int x; - unsigned char leds = ~((atomic_read(&wc->txints) / 1000) % 8) & 0x7; - - /* Skip audio */ - writechunk += 66; - - if (test_bit(VPM150M_SPIRESET, &vpm150m->control) || test_bit(VPM150M_HPIRESET, &vpm150m->control)) { - debug_printk(1, "HW Resetting VPMADT032 ...\n"); - for (x = 0; x < 4; x++) { - if (!x) { - if (test_and_clear_bit(VPM150M_SPIRESET, &vpm150m->control)) - writechunk[CMD_BYTE(x, 0, 1)] = 0x08; - else if (test_and_clear_bit(VPM150M_HPIRESET, &vpm150m->control)) - writechunk[CMD_BYTE(x, 0, 1)] = 0x0b; - } else - writechunk[CMD_BYTE(x, 0, 1)] = 0x00 | leds; - writechunk[CMD_BYTE(x, 1, 1)] = 0; - writechunk[CMD_BYTE(x, 2, 1)] = 0x00; - } - return; - } - - /* Search for something waiting to transmit */ - for (x = 0; x < VPM150M_MAX_COMMANDS; x++) { - if ((vpm150m->cmdq[x].flags & (__VPM150M_RD | __VPM150M_WR)) && - !(vpm150m->cmdq[x].flags & (__VPM150M_FIN | __VPM150M_TX))) { - curcmd = &vpm150m->cmdq[x]; - curcmd->ident = wc->txident; - curcmd->flags |= __VPM150M_TX; - break; - } - } - if (curcmd) { -#if 0 - printk(KERN_DEBUG "Found command txident = %d, desc = 0x%x, addr = 0x%x, data = 0x%x\n", curcmd->txident, curcmd->desc, curcmd->addr, curcmd->data); -#endif - if (curcmd->flags & __VPM150M_RWPAGE) { - /* Set CTRL access to page*/ - writechunk[CMD_BYTE(0, 0, 1)] = (0x8 << 4); - writechunk[CMD_BYTE(0, 1, 1)] = 0; - writechunk[CMD_BYTE(0, 2, 1)] = 0x20; - - /* Do a page write */ - if (curcmd->flags & __VPM150M_WR) - writechunk[CMD_BYTE(1, 0, 1)] = ((0x8 | 0x4) << 4); - else - writechunk[CMD_BYTE(1, 0, 1)] = ((0x8 | 0x4 | 0x1) << 4); - writechunk[CMD_BYTE(1, 1, 1)] = 0; - if (curcmd->flags & __VPM150M_WR) - writechunk[CMD_BYTE(1, 2, 1)] = curcmd->data[0] & 0xf; - else - writechunk[CMD_BYTE(1, 2, 1)] = 0; - - if (curcmd->flags & __VPM150M_WR) { - /* Fill in buffer to size */ - writechunk[CMD_BYTE(2, 0, 1)] = 0; - writechunk[CMD_BYTE(2, 1, 1)] = 0; - writechunk[CMD_BYTE(2, 2, 1)] = 0; - } else { - /* Do reads twice b/c of vpmadt032 bug */ - writechunk[CMD_BYTE(2, 0, 1)] = ((0x8 | 0x4 | 0x1) << 4); - writechunk[CMD_BYTE(2, 1, 1)] = 0; - writechunk[CMD_BYTE(2, 2, 1)] = 0; - } - - /* Clear XADD */ - writechunk[CMD_BYTE(3, 0, 1)] = (0x8 << 4); - writechunk[CMD_BYTE(3, 1, 1)] = 0; - writechunk[CMD_BYTE(3, 2, 1)] = 0; - - /* Fill in buffer to size */ - writechunk[CMD_BYTE(4, 0, 1)] = 0; - writechunk[CMD_BYTE(4, 1, 1)] = 0; - writechunk[CMD_BYTE(4, 2, 1)] = 0; - - } else { - /* Set address */ - writechunk[CMD_BYTE(0, 0, 1)] = ((0x8 | 0x4) << 4); - writechunk[CMD_BYTE(0, 1, 1)] = (curcmd->address >> 8) & 0xff; - writechunk[CMD_BYTE(0, 2, 1)] = curcmd->address & 0xff; - - /* Send/Get our data */ - if (curcmd->flags & __VPM150M_WR) { - if (curcmd->datalen > 1) - writechunk[CMD_BYTE(1, 0, 1)] = ((0x8 | (0x1 << 1)) << 4); - else - writechunk[CMD_BYTE(1, 0, 1)] = ((0x8 | (0x3 << 1)) << 4); - } else - if (curcmd->datalen > 1) - writechunk[CMD_BYTE(1, 0, 1)] = ((0x8 | (0x1 << 1) | 0x1) << 4); - else - writechunk[CMD_BYTE(1, 0, 1)] = ((0x8 | (0x3 << 1) | 0x1) << 4); - writechunk[CMD_BYTE(1, 1, 1)] = (curcmd->data[0] >> 8) & 0xff; - writechunk[CMD_BYTE(1, 2, 1)] = curcmd->data[0] & 0xff; - - if (curcmd->flags & __VPM150M_WR) { - /* Fill in */ - writechunk[CMD_BYTE(2, 0, 1)] = 0; - writechunk[CMD_BYTE(2, 1, 1)] = 0; - writechunk[CMD_BYTE(2, 2, 1)] = 0; - } else { - /* Do this again for reads b/c of the bug in vpmadt032 */ - writechunk[CMD_BYTE(2, 0, 1)] = ((0x8 | (0x3 << 1) | 0x1) << 4); - writechunk[CMD_BYTE(2, 1, 1)] = (curcmd->data[0] >> 8) & 0xff; - writechunk[CMD_BYTE(2, 2, 1)] = curcmd->data[0] & 0xff; - } - - if (curcmd->datalen > 1) { - if (curcmd->flags & __VPM150M_WR) - writechunk[CMD_BYTE(3, 0, 1)] = ((0x8 | (0x1 << 1)) << 4); - else - writechunk[CMD_BYTE(3, 0, 1)] = ((0x8 | (0x1 << 1) | 0x1) << 4); - writechunk[CMD_BYTE(3, 1, 1)] = (curcmd->data[1] >> 8) & 0xff; - writechunk[CMD_BYTE(3, 2, 1)] = curcmd->data[1] & 0xff; - } else { - /* Fill in the rest */ - writechunk[CMD_BYTE(3, 0, 1)] = 0; - writechunk[CMD_BYTE(3, 1, 1)] = 0; - writechunk[CMD_BYTE(3, 2, 1)] = 0; - } - - if (curcmd->datalen > 2) { - if (curcmd->flags & __VPM150M_WR) - writechunk[CMD_BYTE(4, 0, 1)] = ((0x8 | (0x1 << 1)) << 4); - else - writechunk[CMD_BYTE(4, 0, 1)] = ((0x8 | (0x1 << 1) | 0x1) << 4); - writechunk[CMD_BYTE(4, 1, 1)] = (curcmd->data[2] >> 8) & 0xff; - writechunk[CMD_BYTE(4, 2, 1)] = curcmd->data[2] & 0xff; - } else { - /* Fill in the rest */ - writechunk[CMD_BYTE(4, 0, 1)] = 0; - writechunk[CMD_BYTE(4, 1, 1)] = 0; - writechunk[CMD_BYTE(4, 2, 1)] = 0; - } - } - } else if (test_and_clear_bit(VPM150M_SWRESET, &vpm150m->control)) { - debug_printk(1, "Booting VPMADT032\n"); - for (x = 0; x < 7; x++) { - if (x == 0) - writechunk[CMD_BYTE(x, 0, 1)] = (0x8 << 4); - else - writechunk[CMD_BYTE(x, 0, 1)] = 0x00; - writechunk[CMD_BYTE(x, 1, 1)] = 0; - if (x == 0) - writechunk[CMD_BYTE(x, 2, 1)] = 0x01; - else - writechunk[CMD_BYTE(x, 2, 1)] = 0x00; - } - } else { - for (x = 0; x < 7; x++) { - writechunk[CMD_BYTE(x, 0, 1)] = 0x00; - writechunk[CMD_BYTE(x, 1, 1)] = 0x00; - writechunk[CMD_BYTE(x, 2, 1)] = 0x00; - } - } - - /* Add our leds in */ - for (x = 0; x < 7; x++) - writechunk[CMD_BYTE(x, 0, 1)] |= leds; - -#if 0 - int y; - for (x = 0; x < 7; x++) { - for (y = 0; y < 3; y++) { - if (writechunk[CMD_BYTE(x, y, 1)] & 0x2) { - module_printk("the test bit is high for byte %d\n", y); - } - } - } -#endif - - /* Now let's figure out if we need to check for DTMF */ - /* polling */ - if (test_bit(VPM150M_ACTIVE, &vpm150m->control) && !whichframe && !(atomic_read(&wc->txints) % 100)) - queue_work(vpm150m->wq, &vpm150m->work_dtmf); - -#if 0 - /* This may be needed sometime in the future to troubleshoot ADT related issues. */ - if (test_bit(VPM150M_ACTIVE, &vpm150m->control) && !whichframe && !(wc->intcount % 10000)) - queue_work(vpm150m->wq, &vpm150m->work_debug); -#endif -} - -inline void vpm150m_cmd_decipher(struct t1 *wc, volatile unsigned char *readchunk) -{ - unsigned char ident; - int x, i; - - /* Skip audio */ - readchunk += 66; - /* Search for any pending results */ - for (x = 0; x < VPM150M_MAX_COMMANDS; x++) { - if ((wc->vpm150m->cmdq[x].flags & (__VPM150M_RD | __VPM150M_WR)) && - (wc->vpm150m->cmdq[x].flags & (__VPM150M_TX)) && - !(wc->vpm150m->cmdq[x].flags & (__VPM150M_FIN))) { - ident = wc->vpm150m->cmdq[x].ident; - if (ident == wc->rxident) { - /* Store result */ - for (i = 0; i < wc->vpm150m->cmdq[x].datalen; i++) { - wc->vpm150m->cmdq[x].data[i] = (0xff & readchunk[CMD_BYTE((2 + i), 1, 1)]) << 8; - wc->vpm150m->cmdq[x].data[i] |= readchunk[CMD_BYTE((2 + i), 2, 1)]; - } - if (wc->vpm150m->cmdq[x].flags & __VPM150M_WR) { - /* Go ahead and clear out writes since they need no acknowledgement */ - wc->vpm150m->cmdq[x].flags = 0; - } else - wc->vpm150m->cmdq[x].flags |= __VPM150M_FIN; - break; - } - } - } -} - -static inline struct t1 * wc_find_iface(unsigned short dspid) -{ - int i; - struct t1 *ret = NULL; - unsigned long flags; - - spin_lock_irqsave(&ifacelock, flags); - for (i = 0; i < WC_MAX_IFACES; i++) - if (ifaces[i] && ifaces[i]->vpm150m && (ifaces[i]->vpm150m->dspid == dspid)) - ret = ifaces[i]; - spin_unlock_irqrestore(&ifacelock, flags); - - return ret; -} - -static struct vpm150m_cmd * vpm150m_empty_slot(struct t1 *wc) -{ - unsigned int x; - - for (x = 0; x < VPM150M_MAX_COMMANDS; x++) { - if (!wc->vpm150m->cmdq[x].flags) { - return &wc->vpm150m->cmdq[x]; - } - } - return NULL; -} - -/* Wait for any outstanding commands to be completed. */ -static inline int vpm150m_io_wait(struct t1 *wc) -{ - int x; - for (x=0; x < VPM150M_MAX_COMMANDS;) { - if (wc->vpm150m->cmdq[x].flags) { - if (msleep_interruptible(1)) { - return -EINTR; - } - x=0; - } - else { - ++x; - } - } - return 0; -} - -static int t1_vpm150m_getreg_full_async(struct t1 *wc, int pagechange, unsigned int len, - unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p) -{ - int ret=0; - unsigned long flags; - BUG_ON(!hit_p); - spin_lock_irqsave(&wc->reglock, flags); - (*hit_p) = vpm150m_empty_slot(wc); - if (*hit_p) { - (*hit_p)->flags = __VPM150M_RD; - if (pagechange) { - (*hit_p)->flags |= __VPM150M_RWPAGE; - } - (*hit_p)->datalen = len; - (*hit_p)->address = addr; - memset((*hit_p)->data, 0, len*sizeof(outbuf[0])); - } - else { - ret = -EBUSY; - } - spin_unlock_irqrestore(&wc->reglock, flags); - return ret; -} - -static int t1_vpm150m_getreg_full_return(struct t1 *wc, int pagechange, unsigned int len, - unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p) -{ - int ret = 0; - unsigned long flags; - BUG_ON(!hit_p); - spin_lock_irqsave(&wc->reglock, flags); - do { - if ((*hit_p)->flags & __VPM150M_FIN) { - memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0]))); - (*hit_p)->flags = 0; - (*hit_p) = NULL; - ret = 0; - } - else { - spin_unlock_irqrestore(&wc->reglock, flags); - if (msleep_interruptible(1)) { - return -EINTR; - } - spin_lock_irqsave(&wc->reglock, flags); - ret = -EBUSY; - } - } while (-EBUSY == ret); - spin_unlock_irqrestore(&wc->reglock, flags); - return ret; -} - -static int t1_vpm150m_getreg_full(struct t1 *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf) -{ - struct vpm150m_cmd *hit = NULL; - int ret = 0; - do { - ret = t1_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit); - if (!hit) { - if ( -EBUSY == ret ) { - if (msleep_interruptible(1)) - return -EINTR; - } - BUG_ON( 0 != ret); - } - } while (!hit); - - ret = t1_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit); - return ret; -} - -static int t1_vpm150m_setreg_full(struct t1 *wc, int pagechange, unsigned int len, unsigned int addr, unsigned short *data) -{ - unsigned long flags; - struct vpm150m_cmd *hit; - int i; - do { - spin_lock_irqsave(&wc->reglock, flags); - hit = vpm150m_empty_slot(wc); - if (hit) { - hit->flags = __VPM150M_WR; - if (pagechange) - hit->flags |= __VPM150M_RWPAGE; - hit->address = addr; - hit->datalen = len; - for (i = 0; i < len; i++) - hit->data[i] = data[i]; - } - spin_unlock_irqrestore(&wc->reglock, flags); - if (!hit) { - if (msleep_interruptible(1)) - return -EINTR; - } - } while (!hit); - return (hit) ? 0 : -1; -} - -static int t1_vpm150m_setpage(struct t1 *wc, unsigned short addr) -{ - addr &= 0xf; - /* Let's optimize this a little bit */ - if (wc->vpm150m->curpage == addr) - return 0; - else { - wc->vpm150m->curpage = addr; - } - - return t1_vpm150m_setreg_full(wc, 1, 1, 0, &addr); -} - -static unsigned char t1_vpm150m_getpage(struct t1 *wc) -{ - unsigned short res; - t1_vpm150m_getreg_full(wc, 1, 1, 0, &res); - return res; -} - -static int t1_vpm150m_setreg(struct t1 *wc, unsigned int len, unsigned int addr, unsigned short *data) -{ - int res; - t1_vpm150m_setpage(wc, addr >> 16); - if ((addr >> 16) != ((addr + len) >> 16)) - module_printk("setreg: You found it!\n"); - res = t1_vpm150m_setreg_full(wc, 0, len, addr & 0xffff, data); - return res; -} - -static unsigned short t1_vpm150m_getreg(struct t1 *wc, unsigned int len, unsigned int addr, unsigned short *data) -{ - unsigned short res; - t1_vpm150m_setpage(wc, addr >> 16); - if ((addr >> 16) != ((addr + len) >> 16)) - module_printk("getreg: You found it!\n"); - res = t1_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data); - return res; -} - -static char vpm150mtone_to_zaptone(GpakToneCodes_t tone) -{ - switch (tone) { - case DtmfDigit0: - return '0'; - case DtmfDigit1: - return '1'; - case DtmfDigit2: - return '2'; - case DtmfDigit3: - return '3'; - case DtmfDigit4: - return '4'; - case DtmfDigit5: - return '5'; - case DtmfDigit6: - return '6'; - case DtmfDigit7: - return '7'; - case DtmfDigit8: - return '8'; - case DtmfDigit9: - return '9'; - case DtmfDigitPnd: - return '#'; - case DtmfDigitSt: - return '*'; - case DtmfDigitA: - return 'A'; - case DtmfDigitB: - return 'B'; - case DtmfDigitC: - return 'C'; - case DtmfDigitD: - return 'D'; - case EndofCngDigit: - return 'f'; - default: - return 0; - } -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -static void vpm150m_echocan_bh(void *data) -{ - struct vpm150m *vpm150m = data; -#else -static void vpm150m_echocan_bh(struct work_struct *data) -{ - struct vpm150m *vpm150m = container_of(data, struct vpm150m, work_echocan); -#endif - struct t1 *wc = vpm150m->wc; - unsigned long flags; - struct vpm150m_workentry *we; - struct dahdi_chan *chan; - int deflaw; - int res; - GPAK_AlgControlStat_t pstatus; - - while (!list_empty(&vpm150m->worklist)) { - we = list_entry(vpm150m->worklist.next, struct vpm150m_workentry, list); - - spin_lock_irqsave(&vpm150m->lock, flags); - list_del(&we->list); - spin_unlock_irqrestore(&vpm150m->lock, flags); - - chan = we->chan; - - if (we->params.tap_length) { - /* configure channel for the ulaw/alaw */ - unsigned int start = atomic_read(&wc->txints); - - if (memcmp(&we->params, &vpm150m->chan_params[chan->chanpos - 1], sizeof(we->params))) { - /* set parameters */ - vpm150m->chan_params[chan->chanpos - 1] = we->params; - } - - deflaw = chan->span->deflaw; - debug_printk(1, "Enabling EC on channel %d (law %d)\n", chan->chanpos, deflaw); - if (deflaw == 2) /* alaw */ - res = gpakAlgControl(vpm150m->dspid, chan->chanpos - 1, EnableALawSwCompanding, &pstatus); - else if (deflaw == 1) /* alaw */ - res = gpakAlgControl(vpm150m->dspid, chan->chanpos - 1, EnableMuLawSwCompanding, &pstatus); - else { - module_printk("Undefined law for channel %d.\n", chan->chanpos); - res = -1; - } - - if (res) { - module_printk("Unable to set SW Companding on channel %d (reason %d)\n", chan->chanpos, res); - } - - res = gpakAlgControl(vpm150m->dspid, chan->chanpos - 1, EnableEcanA, &pstatus); - debug_printk(2, "Echo can enable took %d ms\n", atomic_read(&wc->txints) - start); - } else { - unsigned int start = atomic_read(&wc->txints); - debug_printk(1, "Disabling EC on channel %d\n", chan->chanpos); - res = gpakAlgControl(vpm150m->dspid, chan->chanpos - 1, BypassSwCompanding, &pstatus); - if (res) - module_printk("Unable to disable sw companding on echo cancellation channel %d (reason %d)\n", chan->chanpos, res); - res = gpakAlgControl(vpm150m->dspid, chan->chanpos - 1, BypassEcanA, &pstatus); - if (res) - module_printk("Unable to disable echo can on channel %d (reason %d)\n", chan->chanpos, res); - debug_printk(2, "Echocan disable took %d ms\n", atomic_read(&wc->txints) - start); - } - if (res) { - module_printk("Unable to toggle echo cancellation on channel %d (reason %d)\n", chan->chanpos, res); - } - - kfree(we); - } -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -static void vpm150m_debug_bh(void *data) -{ - struct vpm150m *vpm150m = data; -#else -static void vpm150m_debug_bh(struct work_struct *data) -{ - struct vpm150m *vpm150m = container_of(data, struct vpm150m, work_debug); -#endif - unsigned short int FrammingError1Count, FramingError2Count, FramingError3Count, - DmaStopErrorCount, DmaSlipStatsBuffer; - - if (gpakReadFramingStats(vpm150m->dspid, &FrammingError1Count, &FramingError2Count, &FramingError3Count, - &DmaStopErrorCount, &DmaSlipStatsBuffer)) - { - module_printk("There was an error getting framing stats.\n"); - } - if (FrammingError1Count||FramingError2Count||FramingError3Count||DmaStopErrorCount||DmaSlipStatsBuffer) - { - module_printk("FramingStats Error: %d %d %d %d %d\n", - FrammingError1Count, FramingError2Count, FramingError3Count, DmaStopErrorCount, DmaSlipStatsBuffer); - } -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -static void vpm150m_dtmf_bh(void *data) -{ - struct vpm150m *vpm150m = data; -#else -static void vpm150m_dtmf_bh(struct work_struct *data) -{ - struct vpm150m *vpm150m = container_of(data, struct vpm150m, work_dtmf); -#endif - struct t1 *wc = vpm150m->wc; - int i; - - for (i = 0; i < wc->span.channels; i++) { - int enable = -1; - if (test_bit(i, &vpm150m->desireddtmfmutestate)) { - if (!test_bit(i, &vpm150m->curdtmfmutestate)) { - enable = 1; - } - } else { - if (test_bit(i, &vpm150m->curdtmfmutestate)) { - enable = 0; - } - } - if (enable > -1) { - unsigned int start = atomic_read(&wc->txints); - GPAK_AlgControlStat_t pstatus; - int res; - - if (enable) { - res = gpakAlgControl(vpm150m->dspid, i, EnableDTMFMuteA, &pstatus); - debug_printk(2, "DTMF mute enable took %d ms\n", atomic_read(&wc->txints) - start); - } else { - res = gpakAlgControl(vpm150m->dspid, i, DisableDTMFMuteA, &pstatus); - debug_printk(2, "DTMF mute disable took %d ms\n", atomic_read(&wc->txints) - start); - } - if (!res) - change_bit(i, &vpm150m->curdtmfmutestate); - } - } - - if (test_bit(VPM150M_DTMFDETECT, &vpm150m->control)) { - unsigned short channel; - GpakAsyncEventCode_t eventcode; - GpakAsyncEventData_t eventdata; - gpakReadEventFIFOMessageStat_t res; - unsigned int start = atomic_read(&wc->txints); - - do { - res = gpakReadEventFIFOMessage(vpm150m->dspid, &channel, &eventcode, &eventdata); - debug_printk(3, "ReadEventFIFOMessage took %d ms\n", atomic_read(&wc->txints) - start); - - if (res == RefInvalidEvent || res == RefDspCommFailure) { - module_printk("Uh oh (%d)\n", res); - continue; - } - - if (eventcode == EventToneDetect) { - GpakToneCodes_t tone = eventdata.toneEvent.ToneCode; - int duration = eventdata.toneEvent.ToneDuration; - char zaptone = vpm150mtone_to_zaptone(tone); - - debug_printk(1, "Channel %d: Detected DTMF tone %d of duration %d\n", channel + 1, tone, duration); - - if (test_bit(channel, &wc->dtmfmask) && (eventdata.toneEvent.ToneDuration > 0)) { - struct dahdi_chan *chan = wc->chans[channel]; - - module_printk("DTMF detected channel=%d tone=%d duration=%d\n", channel + 1, tone, duration); - - if ((tone != EndofMFDigit) && (zaptone != 0)) { - vpm150m->curtone[channel] = tone; - - if (test_bit(channel, &vpm150m->curdtmfmutestate)) { - unsigned long flags; - int y; - - /* Mute the audio data buffers */ - spin_lock_irqsave(&chan->lock, flags); - for (y = 0; y < chan->numbufs; y++) { - if ((chan->inreadbuf > -1) && (chan->readidx[y])) - memset(chan->readbuf[chan->inreadbuf], DAHDI_XLAW(0, chan), chan->readidx[y]); - } - spin_unlock_irqrestore(&chan->lock, flags); - } - if (!test_bit(channel, &wc->dtmfactive)) { - debug_printk(1,"Queuing DTMFDOWN %c\n", zaptone); - set_bit(channel, &wc->dtmfactive); - dahdi_qevent_lock(chan, (DAHDI_EVENT_DTMFDOWN | zaptone)); - } - } else if ((tone == EndofMFDigit) && test_bit(channel, &wc->dtmfactive)) { - debug_printk(1,"Queuing DTMFUP %c\n", vpm150mtone_to_zaptone(vpm150m->curtone[channel])); - dahdi_qevent_lock(chan, (DAHDI_EVENT_DTMFUP | vpm150mtone_to_zaptone(vpm150m->curtone[channel]))); - clear_bit(channel, &wc->dtmfactive); - } - } - } - } while ((res == RefEventAvail)); - } - - return; -} - -void t1_vpm150m_init(struct t1 *wc) { - struct vpm150m *vpm150m; - unsigned short i; - unsigned short reg; - unsigned long flags; - gpakPingDspStat_t pingstatus; - gpakDownloadStatus_t downloadstatus; - struct t1_firmware fw; - struct firmware embedded_firmware; - const struct firmware *firmware = &embedded_firmware; -#if !defined(HOTPLUG_FIRMWARE) - extern void _binary_dahdi_fw_vpmadt032_bin_size; - extern u8 _binary_dahdi_fw_vpmadt032_bin_start[]; -#else - static const char vpmadt032_firmware[] = "dahdi-fw-vpmadt032.bin"; - struct pci_dev* pdev = voicebus_get_pci_dev(wc->vb); -#endif - -#if 0 - unsigned short omsg[4] = { 0xdead, 0xbeef, 0x1111, 0x2222}; - unsigned short imsg[4]; -#endif - - if (!vpmsupport) { - module_printk("VPM Support Disabled\n"); - wc->vpm150m = NULL; - return; - } - - vpm150m = kmalloc(sizeof(struct vpm150m), GFP_KERNEL); - - if (!vpm150m) { - module_printk("Unable to allocate VPMADT032!\n"); - return; - } - memset(vpm150m, 0, sizeof(struct vpm150m)); - - /* Init our vpm150m struct */ - sema_init(&vpm150m->sem, 1); - vpm150m->curpage = 0x80; - - for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) { - if (ifaces[i] == wc) - vpm150m->dspid = i; - } - - debug_printk(1, "Setting VPMADT032 DSP ID to %d\n", vpm150m->dspid); - spin_lock_irqsave(&wc->reglock, flags); - wc->vpm150m = vpm150m; - spin_unlock_irqrestore(&wc->reglock, flags); - - for (i = 0; i < 10; i++) - msleep_interruptible(1); - - debug_printk(1, "Looking for VPMADT032 by testing page access: "); - for (i = 0; i < 0xf; i++) { - int x; - for (x = 0; x < 3; x++) { - t1_vpm150m_setpage(wc, i); - reg = t1_vpm150m_getpage(wc); - if (reg != i) { - /* If they have debug turned on we want them to be able to - * report where in the code the module failed to come up. */ - debug_printk(1, "Either no VPMADT032 module present or the module failed VPM page access test (%x != %x)\n", i, reg); - goto failed_exit; - } - } - } - debug_printk(1, "Passed\n"); - - set_bit(VPM150M_HPIRESET, &vpm150m->control); - msleep(2000); - - /* Set us up to page 0 */ - t1_vpm150m_setpage(wc, 0); - debug_printk(1, "VPMADT032 now doing address test: "); - for (i = 0; i < 16; i++) { - int x; - for (x = 0; x < 2; x++) { - t1_vpm150m_setreg(wc, 1, 0x1000, &i); - t1_vpm150m_getreg(wc, 1, 0x1000, ®); - if (reg != i) { - module_printk("VPMADT032 Failed address test: sent %x != %x on try %d\n", i, reg, x); - goto failed_exit; - } - } - } - debug_printk(1, "Passed\n"); - -#define TEST_SIZE 2 - if (debug) { - unsigned short msg[TEST_SIZE]; - - set_bit(VPM150M_HPIRESET, &vpm150m->control); - msleep(2000); - gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - debug_printk(1, ""); - for (i = 0; i< TEST_SIZE; i++) - printk("%x ", msg[i]); - printk("\n"); - for (i = 0; i< TEST_SIZE; i++) - msg[i] = 0xdead; - gpakWriteDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - gpakWriteDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - debug_printk(1, ""); - for (i = 0; i< TEST_SIZE; i++) - printk("%x ", msg[i]); - printk("\n"); - gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - debug_printk(1, ""); - for (i = 0; i< TEST_SIZE; i++) - printk("%x ", msg[i]); - printk("\n"); - for (i = 0; i< TEST_SIZE; i++) - msg[i] = 0xbeef; - gpakWriteDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - debug_printk(1, ""); - for (i = 0; i< TEST_SIZE; i++) - printk("%x ", msg[i]); - printk("\n"); - gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - debug_printk(1, ""); - for (i = 0; i< TEST_SIZE; i++) - printk("%x ", msg[i]); - printk("\n"); - for (i = 0; i< TEST_SIZE; i++) - msg[i] = 0x1111; - gpakWriteDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - debug_printk(1, ""); - for (i = 0; i< TEST_SIZE; i++) - printk("%x ", msg[i]); - printk("\n"); - gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - debug_printk(1, ""); - for (i = 0; i< TEST_SIZE; i++) - printk("%x ", msg[i]); - printk("\n"); - for (i = 0; i< TEST_SIZE; i++) - msg[i] = 0x2222; - gpakWriteDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - debug_printk(1, ""); - for (i = 0; i< TEST_SIZE; i++) - printk("%x ", msg[i]); - printk("\n"); - gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg); - debug_printk(1, ""); - for (i = 0; i< TEST_SIZE; i++) - printk("%x ", msg[i]); - printk("\n"); - } - -#if defined(HOTPLUG_FIRMWARE) - if ((request_firmware(&firmware, vpmadt032_firmware, &pdev->dev) != 0) || - !firmware) { - printk(KERN_NOTICE "VPMADT032: firmware %s not available from userspace\n", vpmadt032_firmware); - goto failed_exit; - } -#else - embedded_firmware.data = _binary_dahdi_fw_vpmadt032_bin_start; - embedded_firmware.size = (size_t) &_binary_dahdi_fw_vpmadt032_bin_size; -#endif - fw.fw = firmware; - fw.offset = 0; - - set_bit(VPM150M_HPIRESET, &vpm150m->control); - - while (test_bit(VPM150M_HPIRESET, &vpm150m->control)) - msleep(1); - - module_printk("VPMADT032 Loading firmware... "); - downloadstatus = gpakDownloadDsp(vpm150m->dspid, &fw); - - if (firmware != &embedded_firmware) - release_firmware(firmware); - - if (downloadstatus != 0) { - module_printk("Unable to download firmware to VPMADT032 with cause %d\n", downloadstatus); - goto failed_exit; - } else { - module_printk("Success\n"); - } - - set_bit(VPM150M_SWRESET, &vpm150m->control); - - while (test_bit(VPM150M_SWRESET, &vpm150m->control)) - msleep(1); - - msleep(700); -#if 0 - } -#endif - - pingstatus = gpakPingDsp(vpm150m->dspid, &vpm150m->version); - - if (!pingstatus) { - debug_printk(1, "Version of DSP is %x\n", vpm150m->version); - } else { - module_printk("Unable to ping the DSP (%d)!\n", pingstatus); - goto failed_exit; - } - - /* workqueue for DTMF and wc->span functions that cannot sleep */ - spin_lock_init(&vpm150m->lock); - vpm150m->wq = create_singlethread_workqueue("wcte12xp"); - vpm150m->wc = wc; - if (!vpm150m->wq) { - module_printk("Unable to create work queue!\n"); - goto failed_exit; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) - INIT_WORK(&vpm150m->work_echocan, vpm150m_echocan_bh, vpm150m); - INIT_WORK(&vpm150m->work_dtmf, vpm150m_dtmf_bh, vpm150m); - INIT_WORK(&vpm150m->work_debug, vpm150m_debug_bh, vpm150m); -#else - INIT_WORK(&vpm150m->work_echocan, vpm150m_echocan_bh); - INIT_WORK(&vpm150m->work_dtmf, vpm150m_dtmf_bh); - INIT_WORK(&vpm150m->work_debug, vpm150m_debug_bh); -#endif - INIT_LIST_HEAD(&wc->vpm150m->worklist); /* list of echocan tasks */ - - if (vpm150m_config_hw(wc)) { - goto failed_exit; - } - - return; - -failed_exit: - if (vpm150m->wq) { - destroy_workqueue(vpm150m->wq); - } - spin_lock_irqsave(&wc->reglock, flags); - wc->vpm150m = NULL; - spin_unlock_irqrestore(&wc->reglock, flags); - kfree(vpm150m); - - return; -} - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * gpakReadDspMemory - Read DSP memory. - * - * FUNCTION - * This function reads a contiguous block of words from DSP memory starting at - * the specified address. - * - * RETURNS - * nothing - * - */ -void gpakReadDspMemory( - unsigned short int DspId, /* DSP Identifier (0 to MAX_DSP_CORES-1) */ - DSP_ADDRESS DspAddress, /* DSP's memory address of first word */ - unsigned int NumWords, /* number of contiguous words to read */ - DSP_WORD *pWordValues /* pointer to array of word values variable */ - ) -{ - struct t1 *wc = wc_find_iface(DspId); - int i; - int transcount; - int ret; - - vpm150m_io_wait(wc); - if ( NumWords < VPM150M_MAX_COMMANDS ) { - struct vpm150m_cmd* cmds[VPM150M_MAX_COMMANDS] = { NULL }; - t1_vpm150m_setpage(wc, DspAddress >> 16); - DspAddress &= 0xffff; - for (i=0; i < NumWords; ++i) { - ret = t1_vpm150m_getreg_full_async(wc,0,1,DspAddress+i,&pWordValues[i], - &cmds[i]); - if (0 != ret) { - return; - } - } - for (i=NumWords-1; i >=0; --i) { - ret = t1_vpm150m_getreg_full_return(wc,0,1,DspAddress+i,&pWordValues[i], - &cmds[i]); - if (0 != ret) { - return; - } - } - } - else { - for (i = 0; i < NumWords;) { - if ((NumWords - i) > VPM150M_MAX_DATA) - transcount = VPM150M_MAX_DATA; - else - transcount = NumWords - i; - t1_vpm150m_getreg(wc, transcount, DspAddress + i, &pWordValues[i]); - i += transcount; - } - } - return; -} - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * gpakWriteDspMemory - Write DSP memory. - * - * FUNCTION - * This function writes a contiguous block of words to DSP memory starting at - * the specified address. - * - * RETURNS - * nothing - * - */ -void gpakWriteDspMemory( - unsigned short int DspId, /* DSP Identifier (0 to MAX_DSP_CORES-1) */ - DSP_ADDRESS DspAddress, /* DSP's memory address of first word */ - unsigned int NumWords, /* number of contiguous words to write */ - DSP_WORD *pWordValues /* pointer to array of word values to write */ - ) -{ - - struct t1 *wc = wc_find_iface(DspId); - int i; - int transcount; - - if (wc && wc->vpm150m) { - for (i = 0; i < NumWords;) { - if ((NumWords - i) > VPM150M_MAX_DATA) - transcount = VPM150M_MAX_DATA; - else - transcount = NumWords - i; - t1_vpm150m_setreg(wc, transcount, DspAddress + i, &pWordValues[i]); - i += transcount; - } - } - return; - -} - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * gpakHostDelay - Delay for a fixed time interval. - * - * FUNCTION - * This function delays for a fixed time interval before returning. The time - * interval is the Host Port Interface sampling period when polling a DSP for - * replies to command messages. - * - * RETURNS - * nothing - * - */ -void gpakHostDelay(void) -{ -} - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * gpakLockAccess - Lock access to the specified DSP. - * - * FUNCTION - * This function aquires exclusive access to the specified DSP. - * - * RETURNS - * nothing - * - */ -void gpakLockAccess(unsigned short DspId) -{ - struct t1 *wc; - - wc = wc_find_iface(DspId); - - if (wc) { - struct vpm150m *vpm = wc->vpm150m; - - if (vpm) - if (down_interruptible(&vpm->sem)) { - return; - } - } -} - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * gpakUnlockAccess - Unlock access to the specified DSP. - * - * FUNCTION - * This function releases exclusive access to the specified DSP. - * - * RETURNS - * nothing - * - */ -void gpakUnlockAccess(unsigned short DspId) -{ - struct t1 *wc; - - wc = wc_find_iface(DspId); - - if (wc) { - struct vpm150m *vpm = wc->vpm150m; - - if (vpm) - up(&vpm->sem); - } -} - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * gpakReadFile - Read a block of bytes from a G.PAK Download file. - * - * FUNCTION - * This function reads a contiguous block of bytes from a G.PAK Download file - * starting at the current file position. - * - * RETURNS - * The number of bytes read from the file. - * -1 indicates an error occurred. - * 0 indicates all bytes have been read (end of file) - * - */ -int gpakReadFile( - GPAK_FILE_ID FileId, /* G.PAK Download File Identifier */ - unsigned char *pBuffer, /* pointer to buffer for storing bytes */ - unsigned int NumBytes /* number of bytes to read */ - ) -{ - struct t1_firmware *fw = FileId; - unsigned int i, count; - - if (!fw || !fw->fw) - return -1; - - if (NumBytes > (fw->fw->size - fw->offset)) - count = fw->fw->size - fw->offset; - else - count = NumBytes; - - for (i = 0; i < count; i++) - pBuffer[i] = fw->fw->data[fw->offset + i]; - - fw->offset += count; - - return count; -} - -int vpm150m_config_hw(struct t1 *wc) -{ - struct vpm150m *vpm150m = wc->vpm150m; - gpakConfigPortStatus_t configportstatus; - GpakPortConfig_t portconfig; - GPAK_PortConfigStat_t pstatus; - GpakChannelConfig_t chanconfig; - GPAK_ChannelConfigStat_t cstatus; - GPAK_AlgControlStat_t algstatus; - - int res, i; - - memset(&portconfig, 0, sizeof(GpakPortConfig_t)); - - /* First Serial Port config */ - portconfig.SlotsSelect1 = SlotCfgNone; - portconfig.FirstBlockNum1 = 0; - portconfig.FirstSlotMask1 = 0x0000; - portconfig.SecBlockNum1 = 1; - portconfig.SecSlotMask1 = 0x0000; - portconfig.SerialWordSize1 = SerWordSize8; - portconfig.CompandingMode1 = cmpNone; - portconfig.TxFrameSyncPolarity1 = FrameSyncActHigh; - portconfig.RxFrameSyncPolarity1 = FrameSyncActHigh; - portconfig.TxClockPolarity1 = SerClockActHigh; - portconfig.RxClockPolarity1 = SerClockActHigh; - portconfig.TxDataDelay1 = DataDelay0; - portconfig.RxDataDelay1 = DataDelay0; - portconfig.DxDelay1 = Disabled; - portconfig.ThirdSlotMask1 = 0x0000; - portconfig.FouthSlotMask1 = 0x0000; - portconfig.FifthSlotMask1 = 0x0000; - portconfig.SixthSlotMask1 = 0x0000; - portconfig.SevenSlotMask1 = 0x0000; - portconfig.EightSlotMask1 = 0x0000; - - /* Second Serial Port config */ - portconfig.SlotsSelect2 = SlotCfg8Groups; - portconfig.FirstBlockNum2 = 0; - portconfig.FirstSlotMask2 = 0x5554; - portconfig.SecBlockNum2 = 1; - portconfig.SecSlotMask2 = 0x5555; - portconfig.ThirdSlotMask2 = 0x5555; - portconfig.FouthSlotMask2 = 0x5555; - portconfig.SerialWordSize2 = SerWordSize8; - portconfig.CompandingMode2 = cmpNone; - portconfig.TxFrameSyncPolarity2 = FrameSyncActHigh; - portconfig.RxFrameSyncPolarity2 = FrameSyncActHigh; - portconfig.TxClockPolarity2 = SerClockActHigh; - portconfig.RxClockPolarity2 = SerClockActHigh; - portconfig.TxDataDelay2 = DataDelay0; - portconfig.RxDataDelay2 = DataDelay0; - portconfig.DxDelay2 = Disabled; - portconfig.FifthSlotMask2 = 0x0001; - portconfig.SixthSlotMask2 = 0x0000; - portconfig.SevenSlotMask2 = 0x0000; - portconfig.EightSlotMask2 = 0x0000; - - /* Third Serial Port Config */ - portconfig.SlotsSelect3 = SlotCfg8Groups; - portconfig.FirstBlockNum3 = 0; - portconfig.FirstSlotMask3 = 0x5554; - portconfig.SecBlockNum3 = 1; - portconfig.SecSlotMask3 = 0x5555; - portconfig.SerialWordSize3 = SerWordSize8; - portconfig.CompandingMode3 = cmpNone; - portconfig.TxFrameSyncPolarity3 = FrameSyncActHigh; - portconfig.RxFrameSyncPolarity3 = FrameSyncActHigh; - portconfig.TxClockPolarity3 = SerClockActHigh; - portconfig.RxClockPolarity3 = SerClockActLow; - portconfig.TxDataDelay3 = DataDelay0; - portconfig.RxDataDelay3 = DataDelay0; - portconfig.DxDelay3 = Disabled; - portconfig.ThirdSlotMask3 = 0x5555; - portconfig.FouthSlotMask3 = 0x5555; - portconfig.FifthSlotMask3 = 0x0001; - portconfig.SixthSlotMask3 = 0x0000; - portconfig.SevenSlotMask3 = 0x0000; - portconfig.EightSlotMask3 = 0x0000; - - if ((configportstatus = gpakConfigurePorts(vpm150m->dspid, &portconfig, &pstatus))) { - module_printk("Configuration of ports failed (%d)!\n", configportstatus); - return -1; - } else { - debug_printk(1, "Configured McBSP ports successfully\n"); - } - - if ((res = gpakPingDsp(vpm150m->dspid, &vpm150m->version))) { - module_printk("Error pinging DSP (%d)\n", res); - return -1; - } - - for (i = 0; i < 32; i++) { - /* Let's configure a channel */ - chanconfig.PcmInPortA = 3; - chanconfig.PcmInSlotA = (i + 1) * 2; - chanconfig.PcmOutPortA = 2; - chanconfig.PcmOutSlotA = (i + 1) * 2; - chanconfig.PcmInPortB = 2; - chanconfig.PcmInSlotB = (i + 1) * 2; - chanconfig.PcmOutPortB = 3; - chanconfig.PcmOutSlotB = (i + 1) * 2; - if (vpmdtmfsupport) { - chanconfig.ToneTypesA = DTMF_tone; - chanconfig.MuteToneA = Enabled; - chanconfig.FaxCngDetA = Enabled; - } else { - chanconfig.ToneTypesA = Null_tone; - chanconfig.MuteToneA = Disabled; - chanconfig.FaxCngDetA = Disabled; - } - chanconfig.ToneTypesB = Null_tone; - chanconfig.EcanEnableA = Enabled; - chanconfig.EcanEnableB = Disabled; - chanconfig.MuteToneB = Disabled; - chanconfig.FaxCngDetB = Disabled; - - chanconfig.SoftwareCompand = cmpNone; - - chanconfig.FrameRate = rate10ms; - - chanconfig.EcanParametersA.EcanTapLength = 1024; - chanconfig.EcanParametersA.EcanNlpType = vpmnlptype; - chanconfig.EcanParametersA.EcanAdaptEnable = 1; - chanconfig.EcanParametersA.EcanG165DetEnable = 1; - chanconfig.EcanParametersA.EcanDblTalkThresh = 6; - chanconfig.EcanParametersA.EcanNlpThreshold = vpmnlpthresh; - chanconfig.EcanParametersA.EcanNlpConv = 0; - chanconfig.EcanParametersA.EcanNlpUnConv = 0; - chanconfig.EcanParametersA.EcanNlpMaxSuppress = vpmnlpmaxsupp; - chanconfig.EcanParametersA.EcanCngThreshold = 43; - chanconfig.EcanParametersA.EcanAdaptLimit = 50; - chanconfig.EcanParametersA.EcanCrossCorrLimit = 15; - chanconfig.EcanParametersA.EcanNumFirSegments = 3; - chanconfig.EcanParametersA.EcanFirSegmentLen = 64; - - chanconfig.EcanParametersB.EcanTapLength = 1024; - chanconfig.EcanParametersB.EcanNlpType = vpmnlptype; - chanconfig.EcanParametersB.EcanAdaptEnable = 1; - chanconfig.EcanParametersB.EcanG165DetEnable = 1; - chanconfig.EcanParametersB.EcanDblTalkThresh = 6; - chanconfig.EcanParametersB.EcanNlpThreshold = vpmnlpthresh; - chanconfig.EcanParametersB.EcanNlpConv = 0; - chanconfig.EcanParametersB.EcanNlpUnConv = 0; - chanconfig.EcanParametersB.EcanNlpMaxSuppress = vpmnlpmaxsupp; - chanconfig.EcanParametersB.EcanCngThreshold = 43; - chanconfig.EcanParametersB.EcanAdaptLimit = 50; - chanconfig.EcanParametersB.EcanCrossCorrLimit = 15; - chanconfig.EcanParametersB.EcanNumFirSegments = 3; - chanconfig.EcanParametersB.EcanFirSegmentLen = 64; - - if ((res = gpakConfigureChannel(vpm150m->dspid, i, tdmToTdm, &chanconfig, &cstatus))) { - module_printk("Unable to configure channel (%d)\n", res); - if (res == 1) { - module_printk("Reason %d\n", cstatus); - } - - return -1; - } - - if ((res = gpakAlgControl(vpm150m->dspid, i, BypassEcanA, &algstatus))) { - module_printk("Unable to disable echo can on channel %d (reason %d:%d)\n", i + 1, res, algstatus); - return -1; - } - - if (vpmdtmfsupport) { - if ((res = gpakAlgControl(vpm150m->dspid, i, DisableDTMFMuteA, &algstatus))) { - module_printk("Unable to disable dtmf muting on channel %d (reason %d:%d)\n", i + 1, res, algstatus); - return -1; - } - } - } - - if ((res = gpakPingDsp(vpm150m->dspid, &vpm150m->version))) { - module_printk("Error pinging DSP (%d)\n", res); - return -1; - } - - /* Turn on DTMF detection */ - if (vpmdtmfsupport) - set_bit(VPM150M_DTMFDETECT, &vpm150m->control); - set_bit(VPM150M_ACTIVE, &vpm150m->control); - - return 0; -} - -#endif |