From 085c150989f1202fe3321e39803fae633de66ca5 Mon Sep 17 00:00:00 2001 From: mattf Date: Sun, 5 Nov 2006 06:44:13 +0000 Subject: Add support for VPMOCT64 module git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@1556 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wct4xxp/Kbuild | 9 ++-- wct4xxp/Makefile | 10 +++-- wct4xxp/OCT6114-64D.ima | Bin 0 -> 249159 bytes wct4xxp/base.c | 49 ++++++++++++++-------- wct4xxp/vpm450m.c | 107 +++++++++++++++++++++++++++--------------------- wct4xxp/vpm450m.h | 4 +- 6 files changed, 109 insertions(+), 70 deletions(-) create mode 100644 wct4xxp/OCT6114-64D.ima (limited to 'wct4xxp') diff --git a/wct4xxp/Kbuild b/wct4xxp/Kbuild index 8060a97..218eaf5 100644 --- a/wct4xxp/Kbuild +++ b/wct4xxp/Kbuild @@ -12,10 +12,13 @@ wct4xxp-objs := base.o vpm450m.o $(shell $(src)/../oct612x/octasic-helper object $(obj)/base.o: $(src)/vpm450m.h $(src)/wct4xxp.h $(obj)/base.o: $(src)/../zaptel.h -$(obj)/vpm450m.o: $(obj)/vpm450m_fw.h $(src)/vpm450m.h +$(obj)/vpm450m.o: $(obj)/vpmoct128_fw.h $(obj)/vpmoct064_fw.h $(src)/vpm450m.h $(obj)/vpm450m.o: $(src)/../oct612x/include/oct6100api/oct6100_api.h -$(obj)/vpm450m_fw.h: $(src)/OCT6114-128D.ima $(obj)/fw2h +$(obj)/vpmoct128_fw.h: $(src)/OCT6114-128D.ima $(obj)/fw2h $(obj)/fw2h $< $@ -clean-files := vpm450m_fw.h +$(obj)/vpmoct064_fw.h: $(src)/OCT6114-64D.ima $(obj)/fw2h + $(obj)/fw2h $< $@ + +clean-files := vpmoct128_fw.h vpmoct064_fw.h diff --git a/wct4xxp/Makefile b/wct4xxp/Makefile index aea3d12..f6c8173 100644 --- a/wct4xxp/Makefile +++ b/wct4xxp/Makefile @@ -14,19 +14,23 @@ all: wct4xxp.o base.o: ../zaptel.h vpm450m.h wct4xxp.h -vpm450m.o: vpm450m.h vpm450m_fw.h ../oct612x/include/oct6100api/oct6100_api.h +vpm450m.o: vpm450m.h vpmoct128_fw.h vpmoct064_fw.h ../oct612x/include/oct6100api/oct6100_api.h wct4xxp.o: base.o vpm450m.o $(OCTASIC_OBJS) $(LD) -r -o $@ $^ fw2h: CFLAGS= -vpm450m_fw.h: OCT6114-128D.ima fw2h +vpmoct128_fw.h: OCT6114-128D.ima fw2h + ./fw2h $< $@ + +vpmoct064_fw.h: OCT6114-64D.ima fw2h ./fw2h $< $@ clean: rm -f *.o fw2h - rm -f vpm450m_fw.h + rm -f vpmoct128_fw.h + rm -f vpmoct064_fw.h rm -f $(OCTASIC_OBJS) endif diff --git a/wct4xxp/OCT6114-64D.ima b/wct4xxp/OCT6114-64D.ima new file mode 100644 index 0000000..c379320 Binary files /dev/null and b/wct4xxp/OCT6114-64D.ima differ diff --git a/wct4xxp/base.c b/wct4xxp/base.c index bca6ddf..6db860f 100644 --- a/wct4xxp/base.c +++ b/wct4xxp/base.c @@ -2677,6 +2677,8 @@ static void t4_vpm450_init(struct t4 *wc) unsigned int check1, check2; int laws[4] = { 0, }; int x; + int try; + int passedinit = 0; #ifdef HOTPLUG_FIRMWARE const struct firmware *firmware; #endif @@ -2697,31 +2699,46 @@ static void t4_vpm450_init(struct t4 *wc) printk("VPM450: Not Present\n"); return; } + /* First try to load the VPMOCT128 then fallback to VPMOCT064 */ + for (try=0; try<2; try++) { #ifdef HOTPLUG_FIRMWARE - if (request_firmware(&firmware, "OCT6114-128D.ima", &wc->dev->dev) != 0 || !firmware) { - printk("VPM450M: Firmware not found to be loaded\n"); - return; - } - printk("VPM450: Firmware of size %zd found\n", firmware->size); + if (!try) { /* vpmoct128 */ + if (request_firmware(&firmware, "OCT6114-128D.ima", &wc->dev->dev) != 0 || !firmware) { + printk("VPM450M: firmware OCT6114-128D.ima not found to be loaded\n"); + continue; + } + } else { /* vpmoct064 */ + if (request_firmware(&firmware, "OCT6114-64D.ima", &wc->dev->dev) != 0 || !firmware) { + printk("VPM450M: firmware OCT6114-64D not found to be loaded\n"); + return; + } + } + printk("VPM450: Firmware of size %zd found try=%d\n", firmware->size, try+1); #else - printk("VPM450: Using classic method of loading firmware\n"); + printk("VPM450: Using classic method of loading firmware try=%d\n", try+1); #endif - /* Setup alaw vs ulaw rules */ - for (x=0;xnumspans;x++) { - if (wc->tspans[x]->span.channels > 24) - laws[x] = 1; - } + /* Setup alaw vs ulaw rules */ + for (x=0;xnumspans;x++) { + if (wc->tspans[x]->span.channels > 24) + laws[x] = 1; + } #ifdef HOTPLUG_FIRMWARE - if (!(wc->vpm450m = init_vpm450m(wc, laws, firmware))) { + if ((wc->vpm450m = init_vpm450m(wc, laws, wc->numspans, firmware))) { + passedinit=1; + break; + } + release_firmware(firmware); #else - if (!(wc->vpm450m = init_vpm450m(wc, laws))) { + if ((wc->vpm450m = init_vpm450m(wc, laws, wc->numspans))) { + passedinit=1; + break; + } #endif + } + if (!passedinit) { printk("VPM450: Failed to initialize\n"); return; } -#ifdef HOTPLUG_FIRMWARE - release_firmware(firmware); -#endif if (vpmdtmfsupport == -1) { printk("VPM450: hardware DTMF disabled.\n"); vpmdtmfsupport = 0; diff --git a/wct4xxp/vpm450m.c b/wct4xxp/vpm450m.c index 5e52b79..2771837 100644 --- a/wct4xxp/vpm450m.c +++ b/wct4xxp/vpm450m.c @@ -13,7 +13,8 @@ #ifdef HOTPLUG_FIRMWARE #include #else -#include "vpm450m_fw.h" +#include "vpmoct128_fw.h" +#include "vpmoct064_fw.h" #endif #include "oct6100api/oct6100_api.h" @@ -162,6 +163,7 @@ struct vpm450m { UINT32 aulEchoChanHndl[ 128 ]; int chanflags[128]; int ecmode[128]; + int numchans; }; #define FLAG_DTMF (1 << 0) @@ -372,9 +374,9 @@ int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start } #ifdef HOTPLUG_FIRMWARE -struct vpm450m *init_vpm450m(void *wc, int *isalaw, const struct firmware *firmware) +struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware) #else -struct vpm450m *init_vpm450m(void *wc, int *isalaw) +struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans) #endif { tOCT6100_CHIP_OPEN ChipOpen; @@ -390,6 +392,9 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw) memset(vpm450m, 0, sizeof(struct vpm450m)); for (x=0;x<128;x++) vpm450m->ecmode[x] = -1; + + vpm450m->numchans = numspans * 32; + printk("VPM450: echo cancellation for %d channels\n", vpm450m->numchans); Oct6100ChipOpenDef(&ChipOpen); @@ -402,12 +407,17 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw) ChipOpen.pbyImageFile = firmware->data; ChipOpen.ulImageSize = firmware->size; #else - ChipOpen.pbyImageFile = vpm450m_fw; - ChipOpen.ulImageSize = sizeof(vpm450m_fw); + if (vpm450m->numchans > 64) { + ChipOpen.pbyImageFile = vpmoct128_fw; + ChipOpen.ulImageSize = sizeof(vpmoct128_fw); + } else { + ChipOpen.pbyImageFile = vpmoct064_fw; + ChipOpen.ulImageSize = sizeof(vpmoct064_fw); + } #endif ChipOpen.fEnableMemClkOut = TRUE; ChipOpen.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ; - ChipOpen.ulMaxChannels = 128; + ChipOpen.ulMaxChannels = vpm450m->numchans; ChipOpen.ulMemoryType = cOCT6100_MEM_TYPE_DDR; ChipOpen.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB; ChipOpen.ulNumMemoryChips = 1; @@ -442,46 +452,51 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw) return NULL; } for (x=0;x<128;x++) { - /* span timeslots are interleaved 12341234... - * therefore, the lower 2 bits tell us which span this timeslot/channel - */ - if (isalaw[x & 0x03]) - law = cOCT6100_PCM_A_LAW; - else - law = cOCT6100_PCM_U_LAW; - Oct6100ChannelOpenDef(&ChannelOpen); - ChannelOpen.pulChannelHndl = &vpm450m->aulEchoChanHndl[x]; - ChannelOpen.ulUserChanId = x; - ChannelOpen.TdmConfig.ulRinPcmLaw = law; - ChannelOpen.TdmConfig.ulRinStream = 0; - ChannelOpen.TdmConfig.ulRinTimeslot = x; - ChannelOpen.TdmConfig.ulSinPcmLaw = law; - ChannelOpen.TdmConfig.ulSinStream = 1; - ChannelOpen.TdmConfig.ulSinTimeslot = x; - ChannelOpen.TdmConfig.ulSoutPcmLaw = law; - ChannelOpen.TdmConfig.ulSoutStream = 2; - ChannelOpen.TdmConfig.ulSoutTimeslot = x; - ChannelOpen.TdmConfig.ulRoutPcmLaw = law; - ChannelOpen.TdmConfig.ulRoutStream = 3; - ChannelOpen.TdmConfig.ulRoutTimeslot = x; - ChannelOpen.VqeConfig.fEnableNlp = TRUE; - ChannelOpen.VqeConfig.fRinDcOffsetRemoval = TRUE; - ChannelOpen.VqeConfig.fSinDcOffsetRemoval = TRUE; - - ChannelOpen.fEnableToneDisabler = TRUE; - ChannelOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_DIGITAL; - - ulResult = Oct6100ChannelOpen(vpm450m->pApiInstance, &ChannelOpen); - if (ulResult != GENERIC_OK) { - printk("Failed to open channel %d!\n", x); - } - for (y=0;yaulEchoChanHndl[x]; - enable.ulToneNumber = tones[y]; - if (Oct6100ToneDetectionEnable(vpm450m->pApiInstance, &enable) != GENERIC_OK) - printk("Failed to enable tone detection on channel %d for tone %d!\n", x, y); + /* execute this loop always on 4 span cards but + * on 2 span cards only execute for the channels related to our spans */ + if (( numspans > 2) || ((x & 0x03) <2)) { + /* span timeslots are interleaved 12341234... + * therefore, the lower 2 bits tell us which span this + * timeslot/channel + */ + if (isalaw[x & 0x03]) + law = cOCT6100_PCM_A_LAW; + else + law = cOCT6100_PCM_U_LAW; + Oct6100ChannelOpenDef(&ChannelOpen); + ChannelOpen.pulChannelHndl = &vpm450m->aulEchoChanHndl[x]; + ChannelOpen.ulUserChanId = x; + ChannelOpen.TdmConfig.ulRinPcmLaw = law; + ChannelOpen.TdmConfig.ulRinStream = 0; + ChannelOpen.TdmConfig.ulRinTimeslot = x; + ChannelOpen.TdmConfig.ulSinPcmLaw = law; + ChannelOpen.TdmConfig.ulSinStream = 1; + ChannelOpen.TdmConfig.ulSinTimeslot = x; + ChannelOpen.TdmConfig.ulSoutPcmLaw = law; + ChannelOpen.TdmConfig.ulSoutStream = 2; + ChannelOpen.TdmConfig.ulSoutTimeslot = x; + ChannelOpen.TdmConfig.ulRoutPcmLaw = law; + ChannelOpen.TdmConfig.ulRoutStream = 3; + ChannelOpen.TdmConfig.ulRoutTimeslot = x; + ChannelOpen.VqeConfig.fEnableNlp = TRUE; + ChannelOpen.VqeConfig.fRinDcOffsetRemoval = TRUE; + ChannelOpen.VqeConfig.fSinDcOffsetRemoval = TRUE; + + ChannelOpen.fEnableToneDisabler = TRUE; + ChannelOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_DIGITAL; + + ulResult = Oct6100ChannelOpen(vpm450m->pApiInstance, &ChannelOpen); + if (ulResult != GENERIC_OK) { + printk("Failed to open channel %d!\n", x); + } + for (y=0;yaulEchoChanHndl[x]; + enable.ulToneNumber = tones[y]; + if (Oct6100ToneDetectionEnable(vpm450m->pApiInstance, &enable) != GENERIC_OK) + printk("Failed to enable tone detection on channel %d for tone %d!\n", x, y); + } } } return vpm450m; diff --git a/wct4xxp/vpm450m.h b/wct4xxp/vpm450m.h index 350ef1c..6e7454b 100644 --- a/wct4xxp/vpm450m.h +++ b/wct4xxp/vpm450m.h @@ -21,9 +21,9 @@ extern void oct_set_reg(void *data, unsigned int reg, unsigned int val); /* From vpm450m2 */ #ifdef HOTPLUG_FIRMWARE -extern struct vpm450m *init_vpm450m(void *wc, int *isalaw, const struct firmware *firmware); +extern struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware); #else -extern struct vpm450m *init_vpm450m(void *wc, int *isalaw); +extern struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans); #endif extern void vpm450m_setec(struct vpm450m *instance, int channel, int eclen); extern void vpm450m_setdtmf(struct vpm450m *instance, int channel, int dtmfdetect, int dtmfmute); -- cgit v1.2.3