summaryrefslogtreecommitdiff
path: root/wct4xxp
diff options
context:
space:
mode:
authormattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-11-05 06:40:44 +0000
committermattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-11-05 06:40:44 +0000
commit380f72cfaa434030b21dcd14850ad6ec85904240 (patch)
tree3c0ab0ab0005c66d25db5055b0f0de014ee10ed6 /wct4xxp
parent48689826a94c19de3897757c18c07c767a501e43 (diff)
Add support for VPMOCT64 module
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1555 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wct4xxp')
-rw-r--r--wct4xxp/Kbuild9
-rw-r--r--wct4xxp/Makefile10
-rw-r--r--wct4xxp/OCT6114-64D.imabin0 -> 249159 bytes
-rw-r--r--wct4xxp/base.c49
-rw-r--r--wct4xxp/vpm450m.c107
-rw-r--r--wct4xxp/vpm450m.h4
6 files changed, 109 insertions, 70 deletions
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 5c818a4..503b396 100644
--- a/wct4xxp/Makefile
+++ b/wct4xxp/Makefile
@@ -14,7 +14,7 @@ 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 $@ $^
@@ -22,12 +22,16 @@ wct4xxp.o: base.o vpm450m.o $(OCTASIC_OBJS)
fw2h: fw2h.c
$(HOSTCC) -o $@ $^
-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
--- /dev/null
+++ b/wct4xxp/OCT6114-64D.ima
Binary files differ
diff --git a/wct4xxp/base.c b/wct4xxp/base.c
index 72afb05..5d59b04 100644
--- a/wct4xxp/base.c
+++ b/wct4xxp/base.c
@@ -3102,6 +3102,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
@@ -3122,31 +3124,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;x<wc->numspans;x++) {
- if (wc->tspans[x]->span.channels > 24)
- laws[x] = 1;
- }
+ /* Setup alaw vs ulaw rules */
+ for (x=0;x<wc->numspans;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 <linux/firmware.h>
#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;y<sizeof(tones) / sizeof(tones[0]); y++) {
- tOCT6100_TONE_DETECTION_ENABLE enable;
- Oct6100ToneDetectionEnableDef(&enable);
- enable.ulChannelHndl = vpm450m->aulEchoChanHndl[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;y<sizeof(tones) / sizeof(tones[0]); y++) {
+ tOCT6100_TONE_DETECTION_ENABLE enable;
+ Oct6100ToneDetectionEnableDef(&enable);
+ enable.ulChannelHndl = vpm450m->aulEchoChanHndl[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);