summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile10
-rw-r--r--drivers/dahdi/Kbuild27
-rw-r--r--drivers/dahdi/Kconfig19
-rw-r--r--drivers/dahdi/adt_lec.c5
-rw-r--r--drivers/dahdi/firmware/Makefile37
-rw-r--r--drivers/dahdi/voicebus/GpakApi.c (renamed from drivers/dahdi/wcte12xp/GpakApi.c)79
-rw-r--r--drivers/dahdi/voicebus/GpakApi.h (renamed from drivers/dahdi/wctdm24xxp/GpakApi.h)27
-rw-r--r--drivers/dahdi/voicebus/GpakCust.c682
-rw-r--r--drivers/dahdi/voicebus/GpakCust.h (renamed from drivers/dahdi/wctdm24xxp/GpakCust.h)143
-rw-r--r--drivers/dahdi/voicebus/GpakHpi.h (renamed from drivers/dahdi/wctdm24xxp/GpakHpi.h)0
-rw-r--r--drivers/dahdi/voicebus/Kbuild5
-rw-r--r--drivers/dahdi/voicebus/gpakErrs.h (renamed from drivers/dahdi/wctdm24xxp/gpakErrs.h)0
-rw-r--r--drivers/dahdi/voicebus/gpakenum.h (renamed from drivers/dahdi/wctdm24xxp/gpakenum.h)0
-rw-r--r--drivers/dahdi/voicebus/voicebus.c (renamed from drivers/dahdi/voicebus.c)151
-rw-r--r--drivers/dahdi/voicebus/voicebus.h (renamed from drivers/dahdi/voicebus.h)8
-rw-r--r--drivers/dahdi/voicebus/vpmadtreg.c29
-rw-r--r--drivers/dahdi/voicebus/vpmadtreg.h36
-rw-r--r--drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c154
-rw-r--r--drivers/dahdi/wctdm24xxp/GpakApi.c1630
-rw-r--r--drivers/dahdi/wctdm24xxp/GpakCust.c482
-rw-r--r--drivers/dahdi/wctdm24xxp/Kbuild15
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c1262
l---------drivers/dahdi/wctdm24xxp/voicebus.c1
-rw-r--r--drivers/dahdi/wctdm24xxp/wctdm24xxp.h60
-rw-r--r--drivers/dahdi/wcte12xp/GpakApi.h636
-rw-r--r--drivers/dahdi/wcte12xp/GpakErrs.h155
-rw-r--r--drivers/dahdi/wcte12xp/Kbuild15
-rw-r--r--drivers/dahdi/wcte12xp/base.c528
-rw-r--r--drivers/dahdi/wcte12xp/gpakenum.h190
l---------drivers/dahdi/wcte12xp/voicebus.c1
-rw-r--r--drivers/dahdi/wcte12xp/vpmadt032.c1317
-rw-r--r--drivers/dahdi/wcte12xp/vpmadt032.h151
-rw-r--r--drivers/dahdi/wcte12xp/wcte12xp.h8
33 files changed, 2153 insertions, 5710 deletions
diff --git a/Makefile b/Makefile
index 5a7dbdc..7a2be68 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for DAHDI Linux kernel modules
#
-# Copyright (C) 2001-2008 Digium, Inc.
+# Copyright (C) 2001-2009 Digium, Inc.
#
#
@@ -98,7 +98,7 @@ include/dahdi/version.h: FORCE
fi
@rm -f $@.tmp
-prereq: include/dahdi/version.h
+prereq: include/dahdi/version.h firmware-loaders
stackcheck: checkstack modules
./checkstack kernel/*.ko kernel/*/*.ko
@@ -131,6 +131,9 @@ endif
uninstall-firmware:
$(MAKE) -C drivers/dahdi/firmware hotplug-uninstall DESTDIR=$(DESTDIR)
+firmware-loaders:
+ $(MAKE) -C drivers/dahdi/firmware firmware-loaders
+
install-include:
for hdr in $(INST_HEADERS); do \
install -D -m 644 include/dahdi/$$hdr $(DESTDIR)/usr/include/dahdi/$$hdr; \
@@ -233,6 +236,7 @@ distclean: dist-clean
dist-clean: clean
@rm -f include/dahdi/version.h
@$(MAKE) -C drivers/dahdi/firmware dist-clean
+ @rm -f drivers/dahdi/vpmadt032_loader/*.o_shipped
firmware-download:
@$(MAKE) -C drivers/dahdi/firmware all
@@ -245,6 +249,6 @@ docs: $(GENERATED_DOCS)
README.html: README
$(ASCIIDOC_CMD) -o $@ $<
-.PHONY: distclean dist-clean clean all install devices modules stackcheck install-udev update install-modules install-include uninstall-modules firmware-download install-xpp-firm
+.PHONY: distclean dist-clean clean all install devices modules stackcheck install-udev update install-modules install-include uninstall-modules firmware-download install-xpp-firm firmware-loaders
FORCE:
diff --git a/drivers/dahdi/Kbuild b/drivers/dahdi/Kbuild
index c62de64..d897fa8 100644
--- a/drivers/dahdi/Kbuild
+++ b/drivers/dahdi/Kbuild
@@ -10,6 +10,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP) += wctc4xxp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP) += wctdm24xxp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE12XP) += wcte12xp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM) += wctdm.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VOICEBUS) += voicebus/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCB4XXP) += wcb4xxp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT1XXP) += wct1xxp.o
@@ -64,6 +65,32 @@ endif
dahdi-objs := dahdi-base.o
+###############################################################################
+# VPMADT032 Loader
+###############################################################################
+
+dahdi_vpmadt032_loader-objs := vpmadt032_loader/dahdi_vpmadt032_loader.o
+
+ifeq ($(ARCH),i386)
+ ifneq ($(wildcard $(src)/vpmadt032_loader/vpmadt032_x86_32.o_shipped),)
+ VPMADT032_LOADER_PRESENT=yes
+ dahdi_vpmadt032_loader-objs += vpmadt032_loader/vpmadt032_x86_32.o
+ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VPMADT032_LOADER) += dahdi_vpmadt032_loader.o
+ endif
+else
+ ifeq ($(ARCH),x86_64)
+ ifneq ($(wildcard $(src)/vpmadt032_loader/vpmadt032_x86_64.o_shipped),)
+ VPMADT032_LOADER_PRESENT=yes
+ dahdi_vpmadt032_loader-objs += vpmadt032_loader/vpmadt032_x86_64.o
+ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VPMADT032_LOADER) += dahdi_vpmadt032_loader.o
+ endif
+ endif
+endif
+
+###############################################################################
+# HPEC Support
+###############################################################################
+
dahdi_echocan_hpec-objs := hpec/dahdi_echocan_hpec.o
CFLAGS_dahdi_echocan_hpec.o := -I$(src)/hpec
diff --git a/drivers/dahdi/Kconfig b/drivers/dahdi/Kconfig
index 22a448a..4986ccc 100644
--- a/drivers/dahdi/Kconfig
+++ b/drivers/dahdi/Kconfig
@@ -123,9 +123,24 @@ config DAHDI_WCTC4XXP
If unsure, say Y.
+config DAHDI_VOICEBUS
+ tristate "VoiceBus(tm) Interface Library"
+ depends on PCI
+ default DAHDI
+ ---help---
+ This driver provides the common interface for telephony cards that
+ use the VoiceBus(tm) interface. It also contains common supporting
+ libraries for the VPMADT032 hardware echo cancelation module that
+ is available for the VoiceBus cards.
+
+ To compile this driver as a module, choose M here: the module will
+ be called voicebus.
+
+ If unsure, say Y.
+
config DAHDI_WCTDM24XXP
tristate "Digium Wildcard VoiceBus analog card Support"
- depends on DAHDI && PCI
+ depends on DAHDI && DAHDI_VOICEBUS
default DAHDI
---help---
This driver provides support for the following Digium
@@ -145,7 +160,7 @@ config DAHDI_WCTDM24XXP
config DAHDI_WCTE12XP
tristate "Digium Wildcard VoiceBus digital card Support"
- depends on DAHDI && PCI
+ depends on DAHDI && DAHDI_VOICEBUS
default DAHDI
---help---
This driver provides support for the following Digium
diff --git a/drivers/dahdi/adt_lec.c b/drivers/dahdi/adt_lec.c
index 344669d..a566d5d 100644
--- a/drivers/dahdi/adt_lec.c
+++ b/drivers/dahdi/adt_lec.c
@@ -1,7 +1,7 @@
/*
* ADT Line Echo Canceller Parameter Parsing
*
- * Copyright (C) 2008 Digium, Inc.
+ * Copyright (C) 2008-2009 Digium, Inc.
*
* Kevin P. Fleming <kpfleming@digium.com>
*
@@ -33,7 +33,8 @@ static inline void adt_lec_init_defaults(struct adt_lec_params *params, __u32 ta
params->tap_length = tap_length;
}
-static int adt_lec_parse_params(struct adt_lec_params *params, struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
+static int adt_lec_parse_params(struct adt_lec_params *params,
+ struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
{
unsigned int x;
char *c;
diff --git a/drivers/dahdi/firmware/Makefile b/drivers/dahdi/firmware/Makefile
index ae4f945..023279a 100644
--- a/drivers/dahdi/firmware/Makefile
+++ b/drivers/dahdi/firmware/Makefile
@@ -3,7 +3,7 @@
#
# Makefile for firmware downloading/installation
#
-# Copyright (C) 2007-2008, Digium, Inc.
+# Copyright (C) 2007-2009, Digium, Inc.
#
# Joshua Colp <jcolp@digium.com>
#
@@ -11,16 +11,16 @@
# the GNU General Public License
#
-.PHONY: dist-clean clean all uninstall have_download install object-build hotplug-install hotplug-dirs hotplug-uninstall make_firmware_object
+.PHONY: dist-clean clean all uninstall have_download install object-build hotplug-install hotplug-dirs hotplug-uninstall make_firmware_object firmware-loaders
OCT6114_064_VERSION:=1.05.01
OCT6114_128_VERSION:=1.05.01
TC400M_VERSION:=MR6.12
-VPMADT032_VERSION:=1.07
+VPMADT032_VERSION:=1.17.0
FIRMWARE_URL:=http://downloads.digium.com/pub/telephony/firmware/releases
-ALL_FIRMWARE=FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-TC400M FIRMWARE-VPMADT032
+ALL_FIRMWARE=FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-TC400M
# Firmware files should use the naming convention: dahdi-fw-<base name>-<sub name>-<version> or dahdi-fw-<base name>-<version>
# First example: dahdi-fw-oct6114-064-1.05.01
@@ -32,13 +32,13 @@ ALL_FIRMWARE=FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-TC400M FIRMWARE-
FIRMWARE:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064-$(OCT6114_064_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128-$(OCT6114_128_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TC400M=dahdi-fw-tc400m-$(TC400M_VERSION).tar.gz)
-FIRMWARE:=$(FIRMWARE:FIRMWARE-VPMADT032=dahdi-fw-vpmadt032-$(VPMADT032_VERSION).tar.gz)
+
+FWLOADERS:=dahdi-fwload-vpmadt032-$(VPMADT032_VERSION).tar.gz
# Build a list of object files if hotplug will not be used
OBJECT_FILES:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064.o)
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128.o)
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-TC400M=dahdi-fw-tc400m.o)
-OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-VPMADT032=dahdi-fw-vpmadt032.o)
# Force usage of wget, for now
DOWNLOAD=wget
@@ -55,6 +55,7 @@ all: $(FIRMWARE)
dist-clean: clean
rm -f dahdi-fw-*.bin
rm -f dahdi-fw-*.tar.gz
+ rm -f dahdi-fwload-*.tar.gz
rm -f make_firmware_object
# Clean up anything we built
@@ -70,6 +71,14 @@ dahdi-fw-%.tar.gz:
(cat $@ | gzip -d | tar -xof -) \
fi
+firmware-loaders: $(FWLOADERS)
+
+.PHONY: dahdi-fwload-vpmadt032-$(VPMADT032_VERSION).tar.gz
+dahdi-fwload-vpmadt032-$(VPMADT032_VERSION).tar.gz:
+ @if test ! -f $@; then echo "Attempting to download $@"; $(DOWNLOAD) $(WGET_ARGS) $(FIRMWARE_URL)/$@; fi; \
+ if test ! -f $@; then exit 1; fi; \
+ (cd ../../..; cat drivers/dahdi/firmware/$@ | gzip -d | tar -xof -)
+
# Create object files suitable for linking against
object-build: $(FIRMWARE) $(OBJECT_FILES)
@@ -111,17 +120,6 @@ ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-$(T
else
@echo "Firmware dahdi-fw-tc400m.bin is already installed with required version $(TC400M_VERSION)"
endif
-ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmadt032-$(VPMADT032_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-vpmadt032-$(VPMADT032_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
- @echo "Installing dahdi-fw-vpmadt032.bin to hotplug firmware directories"
- @install -m 644 dahdi-fw-vpmadt032.bin $(DESTDIR)/usr/lib/hotplug/firmware
- @rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmadt032-*
- @touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmadt032-$(VPMADT032_VERSION)
- @install -m 644 dahdi-fw-vpmadt032.bin $(DESTDIR)/lib/firmware
- @rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-vpmadt032-*
- @touch $(DESTDIR)/lib/firmware/.dahdi-fw-vpmadt032-$(VPMADT032_VERSION)
-else
- @echo "Firmware dahdi-fw-vpmadt032.bin is already installed with required version $(VPMADT032_VERSION)"
-endif
# Uninstall any installed dahdi firmware images from hotplug firmware directories
hotplug-uninstall:
@@ -154,8 +152,3 @@ dahdi-fw-oct6114-128.o: dahdi-fw-oct6114-128-$(OCT6114_128_VERSION).tar.gz dahdi
dahdi-fw-tc400m.o: dahdi-fw-tc400m-$(TC400M_VERSION).tar.gz dahdi-fw-tc400m.bin make_firmware_object
@echo Making firmware object file for dahdi-fw-tc400m.bin
./make_firmware_object dahdi-fw-tc400m.bin $@
-
-# Build object file of a VPMADT032 firmware image for linking
-dahdi-fw-vpmadt032.o: dahdi-fw-vpmadt032-$(VPMADT032_VERSION).tar.gz dahdi-fw-vpmadt032.bin make_firmware_object
- @echo Making firmware object file for dahdi-fw-vpmadt032.bin
- ./make_firmware_object dahdi-fw-vpmadt032.bin $@
diff --git a/drivers/dahdi/wcte12xp/GpakApi.c b/drivers/dahdi/voicebus/GpakApi.c
index 748cc94..4b480ab 100644
--- a/drivers/dahdi/wcte12xp/GpakApi.c
+++ b/drivers/dahdi/voicebus/GpakApi.c
@@ -16,6 +16,7 @@
*
* This program has been released under the terms of the GPL version 2 by
* permission of Adaptive Digital Technologies, Inc.
+ *
*/
/*
@@ -31,15 +32,11 @@
* this program for more details.
*/
-#include <dahdi/kernel.h>
-
#include "GpakHpi.h"
-#include "vpmadt032.h"
+#include "GpakCust.h"
#include "GpakApi.h"
#include "gpakenum.h"
-#ifdef VPM_SUPPORT
-
/* DSP to Host interface block offsets. */
#define REPLY_MSG_PNTR_OFFSET 0 /* I/F blk offset to Reply Msg Pointer */
#define CMD_MSG_PNTR_OFFSET 2 /* I/F blk offset to Command Msg Pointer */
@@ -127,11 +124,6 @@ static int CheckDspReset(
DSP_WORD DspStatus; /* DSP Status */
DSP_WORD DspChannels; /* number of DSP channels */
DSP_WORD Temp[2];
-#if 0
- DSP_WORD DspConfs; /* number of DSP conferences */
- DSP_ADDRESS PktBufrMem; /* address of Packet Buffer */
- unsigned short int i; /* loop index / counter */
-#endif
/* Read the pointer to the Interface Block. */
gpakReadDspMemory(DspId, DSP_IFBLK_ADDRESS, 2, Temp);
@@ -164,38 +156,6 @@ static int CheckDspReset(
MaxChannels[DspId] = MAX_CHANNELS;
else
MaxChannels[DspId] = (unsigned short int) DspChannels;
-#if 0
- /* read the number of configured DSP conferences */
- gpakReadDspMemory(DspId, IfBlockPntr + NUM_CONFERENCES_OFFSET, 1,
- &DspConfs);
- if (DspConfs > MAX_CONFS)
- MaxConfs[DspId] = MAX_CONFS;
- else
- MaxConfs[DspId] = (unsigned short int) DspConfs;
-
-
- /* read the number of configured DSP packet channels */
- gpakReadDspMemory(DspId, IfBlockPntr + NUM_PKT_CHANNELS_OFFSET, 1,
- &DspChannels);
- if (DspChannels > MAX_PKT_CHANNELS)
- MaxPktChannels[DspId] = MAX_PKT_CHANNELS;
- else
- MaxPktChannels[DspId] = (unsigned short int) DspChannels;
-
-
- /* read the pointer to the circular buffer infor struct table */
- gpakReadDspMemory(DspId, IfBlockPntr + PKT_BUFR_MEM_OFFSET, 2, Temp);
- RECONSTRUCT_LONGWORD(PktBufrMem, Temp);
-
-
- /* Determine the addresses of each channel's Packet buffers. */
- for (i = 0; i < MaxPktChannels[DspId]; i++)
- {
- pPktInBufr[DspId][i] = PktBufrMem;
- pPktOutBufr[DspId][i] = PktBufrMem + CIRC_BUFFER_INFO_STRUCT_SIZE;
- PktBufrMem += (CIRC_BUFFER_INFO_STRUCT_SIZE*2);
- }
-#endif
/* read the pointer to the event fifo info struct */
gpakReadDspMemory(DspId, IfBlockPntr + EVENT_MSG_PNTR_OFFSET, 2, Temp);
@@ -509,7 +469,7 @@ static unsigned int TransactCmd(
*/
gpakConfigPortStatus_t gpakConfigurePorts(
unsigned short int DspId, /* DSP Id (0 to MaxDSPCores-1) */
- GpakPortConfig_t *pPortConfig, /* pointer to Port Config info */
+ const GpakPortConfig_t *pPortConfig, /* pointer to Port Config info */
GPAK_PortConfigStat_t *pStatus /* pointer to Port Config Status */
)
{
@@ -560,7 +520,7 @@ gpakConfigPortStatus_t gpakConfigurePorts(
((pPortConfig->RxFrameSyncPolarity2 << 4) & 0x0010) |
((pPortConfig->TxFrameSyncPolarity2 << 3) & 0x0008) |
((pPortConfig->CompandingMode2 << 1) & 0x0006) |
- (pPortConfig->SerialWordSize1 & 0x0001));
+ (pPortConfig->SerialWordSize2 & 0x0001));
MsgBuffer[12] = (DSP_WORD)
(((pPortConfig->DxDelay3 << 11) & 0x0800) |
@@ -608,6 +568,7 @@ gpakConfigPortStatus_t gpakConfigurePorts(
else
return (CpsParmError);
}
+EXPORT_SYMBOL(gpakConfigurePorts);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -672,7 +633,7 @@ gpakConfigChanStatus_t gpakConfigureChannel(
((pChanConfig->SoftwareCompand & 3) << 2) |
(pChanConfig->EcanEnableB << 1) |
(pChanConfig->EcanEnableA & 1)
- );
+ );
MsgBuffer[7] = (DSP_WORD)
pChanConfig->EcanParametersA.EcanTapLength;
@@ -733,7 +694,22 @@ gpakConfigChanStatus_t gpakConfigureChannel(
MsgBuffer[34] = (DSP_WORD)
pChanConfig->EcanParametersB.EcanFirSegmentLen;
- MsgLength = 70; // byte number == 35*2
+ MsgBuffer[35] = (DSP_WORD)
+ (
+ ((pChanConfig->EcanParametersB.EcanReconvergenceCheckEnable <<5) & 0x20) |
+ ((pChanConfig->EcanParametersA.EcanReconvergenceCheckEnable <<4) & 0x10) |
+ ((pChanConfig->EcanParametersB.EcanTandemOperationEnable <<3) & 0x8) |
+ ((pChanConfig->EcanParametersA.EcanTandemOperationEnable <<2) & 0x4) |
+ ((pChanConfig->EcanParametersB.EcanMixedFourWireMode << 1) & 0x2) |
+ (pChanConfig->EcanParametersA.EcanMixedFourWireMode & 1)
+ );
+ MsgBuffer[36] = (DSP_WORD)
+ pChanConfig->EcanParametersA.EcanMaxDoubleTalkThres;
+
+ MsgBuffer[37] = (DSP_WORD)
+ pChanConfig->EcanParametersB.EcanMaxDoubleTalkThres;
+
+ MsgLength = 76; // byte number == 38*2
break;
@@ -760,6 +736,7 @@ gpakConfigChanStatus_t gpakConfigureChannel(
else
return (CcsParmError);
}
+EXPORT_SYMBOL(gpakConfigureChannel);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* gpakTearDownChannel - Tear Down a DSP's Channel.
@@ -852,6 +829,7 @@ gpakAlgControlStat_t gpakAlgControl(
return (AcParmError);
}
+EXPORT_SYMBOL(gpakAlgControl);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* gpakReadEventFIFOMessage - read from the event fifo
@@ -889,9 +867,6 @@ gpakReadEventFIFOMessageStat_t gpakReadEventFIFOMessage(
DSP_WORD TakeIndex; /* event fifo take index */
DSP_WORD WordsReady; /* number words ready for read out of event fifo */
DSP_WORD EventError; /* flag indicating error with event fifo msg */
-#if 0
- DSP_WORD *pDebugData; /* debug data buffer pointer in event data struct */
-#endif
/* Make sure the DSP Id is valid. */
if (DspId >= MAX_DSP_CORES)
@@ -911,7 +886,7 @@ gpakReadEventFIFOMessageStat_t gpakReadEventFIFOMessage(
EventInfoAddress = pEventFifoAddress[DspId];
gpakReadDspMemory(DspId, EventInfoAddress, CIRC_BUFFER_INFO_STRUCT_SIZE,
WordBuffer);
- RECONSTRUCT_LONGWORD(BufrBaseAddress, ((DSP_WORD *)&WordBuffer[CB_BUFR_BASE]));
+ RECONSTRUCT_LONGWORD(BufrBaseAddress, ((DSP_WORD *)&WordBuffer[CB_BUFR_BASE]));
BufrSize = WordBuffer[CB_BUFR_SIZE];
PutIndex = WordBuffer[CB_BUFR_PUT_INDEX];
TakeIndex = WordBuffer[CB_BUFR_TAKE_INDEX];
@@ -1025,6 +1000,7 @@ gpakPingDspStat_t gpakPingDsp(
else
return (PngDspCommFailure);
}
+EXPORT_SYMBOL(gpakPingDsp);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* gpakSerialTxFixedValue - transmit a fixed value on a timeslot
@@ -1249,7 +1225,7 @@ gpakReadFramingStatsStatus_t gpakReadFramingStats(
*pFramingError3Count = ReadBuffer[2];
*pDmaStopErrorCount = ReadBuffer[3];
- if(pDmaSlipStatsBuffer != NULL)
+ if(pDmaSlipStatsBuffer != 0)
// If users want to get the DMA slips count
{
pDmaSlipStatsBuffer[0] = ReadBuffer[4];
@@ -1612,4 +1588,3 @@ gpakReadSysParmsStatus_t gpakReadSystemParms(
/* Return with an indication that System Parameters info was obtained. */
return (RspSuccess);
}
-#endif
diff --git a/drivers/dahdi/wctdm24xxp/GpakApi.h b/drivers/dahdi/voicebus/GpakApi.h
index 2e55e64..91aade0 100644
--- a/drivers/dahdi/wctdm24xxp/GpakApi.h
+++ b/drivers/dahdi/voicebus/GpakApi.h
@@ -14,23 +14,6 @@
* Revision History:
* 06/15/05 - Initial release.
* 11/15/2006 - 24 TDM-TDM Channels EC release
- *
- * This program has been released under the terms of the GPL version 2 by
- * permission of Adaptive Digital Technologies, Inc.
- *
- */
-
-/*
- * 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.
*/
#ifndef _GPAKAPI_H /* prevent multiple inclusion */
@@ -67,6 +50,7 @@ typedef struct
short int EcanAdaptEnable; // Echo Can Adapt Enable flag
short int EcanG165DetEnable; // Echo Can G165 Detect Enable flag
short int EcanDblTalkThresh; // Echo Can Double Talk threshold
+ short int EcanMaxDoubleTalkThres; // Maximum double-talk threshold
short int EcanNlpThreshold; // Echo Can NLP threshold
short int EcanNlpConv; // Dynamic NLP control, NLP limit when EC about to converged
short int EcanNlpUnConv;// Dynamic NLP control, NLP limit when EC not converged yet
@@ -76,10 +60,13 @@ typedef struct
short int EcanCrossCorrLimit; // Echo Can Cross Correlation limit
short int EcanNumFirSegments; // Echo Can Num FIR Segments
short int EcanFirSegmentLen; // Echo Can FIR Segment Length
+ short int EcanTandemOperationEnable; //Enable tandem operation
+ short int EcanMixedFourWireMode; // Handle possible 4-wire (echo-free) lines
+ short int EcanReconvergenceCheckEnable; // Handle possible 4-wire (echo-free) lines
} GpakEcanParms_t;
/* Definition of a Channel Configuration information structure. */
-typedef struct
+typedef struct GpakChannelConfig
{
GpakSerialPort_t PcmInPortA; // A side PCM Input Serial Port Id
unsigned short int PcmInSlotA; // A side PCM Input Time Slot
@@ -106,7 +93,7 @@ typedef struct
/* Definition of a Serial Port Configuration Structure */
-typedef struct
+typedef struct GpakPortConfig
{
GpakSlotCfg_t SlotsSelect1; // port 1 Slot selection
unsigned short int FirstBlockNum1; // port 1 first group Block Number
@@ -302,7 +289,7 @@ typedef enum
*/
extern gpakConfigPortStatus_t gpakConfigurePorts(
unsigned short int DspId, // DSP identifier
- GpakPortConfig_t *pPortConfig, // pointer to Port Config info
+ const GpakPortConfig_t *pPortConfig, // pointer to Port Config info
GPAK_PortConfigStat_t *pStatus // pointer to Port Config Status
);
diff --git a/drivers/dahdi/voicebus/GpakCust.c b/drivers/dahdi/voicebus/GpakCust.c
new file mode 100644
index 0000000..386c916
--- /dev/null
+++ b/drivers/dahdi/voicebus/GpakCust.c
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2005, Adaptive Digital Technologies, Inc.
+ * Copyright (c) 2005-2009, Digium Incorporated
+ *
+ * File Name: GpakCust.c
+ *
+ * Description:
+ * This file contains host system dependent functions to support generic
+ * G.PAK API functions. The file is integrated into the host processor
+ * connected to C55x G.PAK DSPs via a Host Port Interface.
+ *
+ * Note: This file is supplied by Adaptive Digital Technologies and
+ * modified by Digium in order to support the VPMADT032 modules.
+ *
+ * This program has been released under the terms of the GPL version 2 by
+ * permission of Adaptive Digital Technologies, Inc.
+ *
+ */
+
+/*
+ * 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/version.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#include <linux/semaphore.h>
+#else
+#include <asm/semaphore.h>
+#endif
+
+#include <dahdi/kernel.h>
+#include <dahdi/user.h>
+
+#include "GpakCust.h"
+#include "GpakApi.h"
+
+#include "adt_lec.h"
+#include "voicebus.h"
+#include "vpmadtreg.h"
+
+static rwlock_t ifacelock;
+static struct vpmadt032 *ifaces[MAX_DSP_CORES];
+
+static inline struct vpmadt032 *find_iface(const unsigned short dspid)
+{
+ struct vpmadt032 *ret;
+
+ read_lock(&ifacelock);
+ if (ifaces[dspid]) {
+ ret = ifaces[dspid];
+ } else {
+ ret = NULL;
+ }
+ read_unlock(&ifacelock);
+ return ret;
+}
+
+static struct vpmadt032_cmd *vpmadt032_get_free_cmd(struct vpmadt032 *vpm)
+{
+ unsigned long flags;
+ struct vpmadt032_cmd *cmd;
+ might_sleep();
+ spin_lock_irqsave(&vpm->list_lock, flags);
+ if (list_empty(&vpm->free_cmds)) {
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+ cmd = kmalloc(sizeof(struct vpmadt032_cmd), GFP_KERNEL);
+ if (unlikely(!cmd))
+ return NULL;
+ memset(cmd, 0, sizeof(*cmd));
+ } else {
+ cmd = list_entry(vpm->free_cmds.next, struct vpmadt032_cmd, node);
+ list_del_init(&cmd->node);
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+ }
+ init_completion(&cmd->complete);
+ return cmd;
+}
+
+/* Wait for any outstanding commands to the VPMADT032 to complete */
+static inline int vpmadt032_io_wait(struct vpmadt032 *vpm)
+{
+ unsigned long flags;
+ int empty;
+ while (1) {
+ spin_lock_irqsave(&vpm->list_lock, flags);
+ empty = list_empty(&vpm->pending_cmds) && list_empty(&vpm->active_cmds);
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+ if (empty) {
+ break;
+ } else {
+ msleep(1);
+ }
+ }
+ return 0;
+}
+
+/* Issue a read command to a register on the VPMADT032. We'll get the results
+ * later. */
+static struct vpmadt032_cmd *vpmadt032_getreg_full_async(struct vpmadt032 *vpm, int pagechange,
+ unsigned short addr)
+{
+ unsigned long flags;
+ struct vpmadt032_cmd *cmd;
+ cmd = vpmadt032_get_free_cmd(vpm);
+ if (!cmd)
+ return NULL;
+ cmd->desc = (pagechange) ? __VPM150M_RWPAGE | __VPM150M_RD : __VPM150M_RD;
+ cmd->address = addr;
+ cmd->data = 0;
+ spin_lock_irqsave(&vpm->list_lock, flags);
+ list_add_tail(&cmd->node, &vpm->pending_cmds);
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+ return cmd;
+}
+
+/* Get the results from a previous call to vpmadt032_getreg_full_async. */
+int vpmadt032_getreg_full_return(struct vpmadt032 *vpm, int pagechange,
+ u16 addr, u16 *outbuf, struct vpmadt032_cmd *cmd)
+{
+ unsigned long flags;
+ int ret = -EIO;
+ BUG_ON(!cmd);
+ wait_for_completion(&cmd->complete);
+ if (cmd->desc & __VPM150M_FIN) {
+ *outbuf = cmd->data;
+ cmd->desc = 0;
+ ret = 0;
+ }
+
+ /* Just throw this command back on the ready list. */
+ spin_lock_irqsave(&vpm->list_lock, flags);
+ list_add_tail(&cmd->node, &vpm->free_cmds);
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+ return ret;
+}
+
+/* Read one of the registers on the VPMADT032 */
+static int vpmadt032_getreg_full(struct vpmadt032 *vpm, int pagechange, u16 addr, u16 *outbuf)
+{
+ struct vpmadt032_cmd *cmd;
+ cmd = vpmadt032_getreg_full_async(vpm, pagechange, addr);
+ if (unlikely(!cmd)) {
+ return -ENOMEM;
+ }
+ return vpmadt032_getreg_full_return(vpm, pagechange, addr, outbuf, cmd);
+}
+
+static int vpmadt032_setreg_full(struct vpmadt032 *vpm, int pagechange, unsigned int addr,
+ u16 data)
+{
+ unsigned long flags;
+ struct vpmadt032_cmd *cmd;
+ cmd = vpmadt032_get_free_cmd(vpm);
+ if (!cmd)
+ return -ENOMEM;
+ cmd->desc = cpu_to_le16((pagechange) ? (__VPM150M_WR|__VPM150M_RWPAGE) : __VPM150M_WR);
+ cmd->address = cpu_to_le16(addr);
+ cmd->data = cpu_to_le16(data);
+ spin_lock_irqsave(&vpm->list_lock, flags);
+ list_add_tail(&cmd->node, &vpm->pending_cmds);
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+ return 0;
+}
+
+
+static int vpmadt032_setpage(struct vpmadt032 *vpm, u16 addr)
+{
+ addr &= 0xf;
+ /* We do not need to set the page if we're already on the page we're
+ * interested in. */
+ if (vpm->curpage == addr)
+ return 0;
+ else
+ vpm->curpage = addr;
+
+ return vpmadt032_setreg_full(vpm, 1, 0, addr);
+}
+
+static unsigned char vpmadt032_getpage(struct vpmadt032 *vpm)
+{
+ unsigned short res;
+ const int pagechange = 1;
+ vpmadt032_getreg_full(vpm, pagechange, 0, &res);
+ return res;
+}
+
+static int vpmadt032_getreg(struct vpmadt032 *vpm, unsigned int addr, u16 *data)
+{
+ unsigned short res;
+ vpmadt032_setpage(vpm, addr >> 16);
+ res = vpmadt032_getreg_full(vpm, 0, addr & 0xffff, data);
+ return res;
+}
+
+static int vpmadt032_setreg(struct vpmadt032 *vpm, unsigned int addr, u16 data)
+{
+ int res;
+ vpmadt032_setpage(vpm, addr >> 16);
+ res = vpmadt032_setreg_full(vpm, 0, addr & 0xffff, data);
+ return res;
+}
+
+/**
+ * vpmadt032_bh - Changes the echocan parameters on the vpmadt032 module.
+ *
+ * This function is typically scheduled to run in the workqueue by the
+ * vpmadt032_echocan_with_params function. This is because communicating with
+ * the hardware can take some time while messages are sent to the VPMADT032
+ * module and the driver waits for the responses.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+static void vpmadt032_bh(void *data)
+{
+ struct vpmadt032 *vpm = data;
+#else
+static void vpmadt032_bh(struct work_struct *data)
+{
+ struct vpmadt032 *vpm = container_of(data, struct vpmadt032, work);
+#endif
+ struct adt_lec_params *curstate, *desiredstate;
+ int channel;
+
+ /* Sweep through all the echo can channels on the VPMADT032 module,
+ * looking for ones where the desired state does not match the current
+ * state.
+ */
+ for (channel = 0; channel < vpm->span->channels; channel++) {
+ GPAK_AlgControlStat_t pstatus;
+ int res = 1;
+ curstate = &vpm->curecstate[channel];
+ desiredstate = &vpm->desiredecstate[channel];
+
+ if ((desiredstate->nlp_type != curstate->nlp_type) ||
+ (desiredstate->nlp_threshold != curstate->nlp_threshold) ||
+ (desiredstate->nlp_max_suppress != curstate->nlp_max_suppress)) {
+
+ GPAK_ChannelConfigStat_t cstatus;
+ GPAK_TearDownChanStat_t tstatus;
+ GpakChannelConfig_t chanconfig;
+
+ if (vpm->options.debug & DEBUG_ECHOCAN)
+ printk(KERN_DEBUG "Reconfiguring chan %d for nlp %d, nlp_thresh %d, and max_supp %d\n", channel + 1, vpm->desiredecstate[channel].nlp_type,
+ desiredstate->nlp_threshold, desiredstate->nlp_max_suppress);
+
+ vpm->setchanconfig_from_state(vpm, channel, &chanconfig);
+
+ res = gpakTearDownChannel(vpm->dspid, channel, &tstatus);
+ if (res)
+ goto vpm_bh_out;
+
+ res = gpakConfigureChannel(vpm->dspid, channel, tdmToTdm, &chanconfig, &cstatus);
+ if (res)
+ goto vpm_bh_out;
+
+ if (!desiredstate->tap_length) {
+ res = gpakAlgControl(vpm->dspid, channel, BypassSwCompanding, &pstatus);
+ if (res)
+ printk("Unable to disable sw companding on echo cancellation channel %d (reason %d)\n", channel, res);
+ res = gpakAlgControl(vpm->dspid, channel, BypassEcanA, &pstatus);
+ }
+
+ } else if (desiredstate->tap_length != curstate->tap_length) {
+ if (desiredstate->tap_length) {
+ printk(KERN_DEBUG "Enabling ecan on channel: %d\n", channel);
+ res = gpakAlgControl(vpm->dspid, channel, EnableMuLawSwCompanding, &pstatus);
+ if (res)
+ printk("Unable to set SW Companding on channel %d (reason %d)\n", channel, res);
+ res = gpakAlgControl(vpm->dspid, channel, EnableEcanA, &pstatus);
+ } else {
+ printk(KERN_DEBUG "Disabling ecan on channel: %d\n", channel);
+ res = gpakAlgControl(vpm->dspid, channel, BypassSwCompanding, &pstatus);
+ if (res)
+ printk("Unable to disable sw companding on echo cancellation channel %d (reason %d)\n", channel, res);
+ res = gpakAlgControl(vpm->dspid, channel, BypassEcanA, &pstatus);
+ }
+ }
+vpm_bh_out:
+ if (!res)
+ *curstate = *desiredstate;
+ }
+ return;
+}
+#include "adt_lec.c"
+int vpmadt032_echocan_with_params(struct vpmadt032 *vpm, int channo,
+ struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
+{
+ int update;
+ unsigned int ret;
+
+ ret = adt_lec_parse_params(&vpm->desiredecstate[channo], ecp, p);
+ if (ret)
+ return ret;
+
+ /* The driver cannot control the number of taps on the VPMADT032
+ * module. Instead, it uses tap_length to enable or disable the echo
+ * cancellation. */
+ vpm->desiredecstate[channo].tap_length = (ecp->tap_length) ? 1 : 0;
+
+ /* Only update the parameters if the new state of the echo canceller
+ * is different than the current state. */
+ update = memcmp(&vpm->curecstate[channo],
+ &vpm->desiredecstate[channo],
+ sizeof(vpm->curecstate[channo]));
+ if (update && test_bit(VPM150M_ACTIVE, &vpm->control)) {
+ /* Since updating the parameters can take a bit of time while
+ * the driver sends messages to the VPMADT032 and waits for
+ * their responses, we'll push the work of updating the
+ * parameters to a work queue so the caller can continue to
+ * proceed with setting up the call.
+ */
+ schedule_work(&vpm->work);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(vpmadt032_echocan_with_params);
+
+struct vpmadt032 *vpmadt032_alloc(struct vpmadt032_options *options)
+{
+ struct vpmadt032 *vpm;
+ int i;
+ might_sleep();
+
+ vpm = kzalloc(sizeof(*vpm), GFP_KERNEL);
+ if (!vpm)
+ return NULL;
+
+ /* Init our vpmadt032 struct */
+ memcpy(&vpm->options, options, sizeof(*options));
+ spin_lock_init(&vpm->list_lock);
+ INIT_LIST_HEAD(&vpm->free_cmds);
+ INIT_LIST_HEAD(&vpm->pending_cmds);
+ INIT_LIST_HEAD(&vpm->active_cmds);
+ sema_init(&vpm->sem, 1);
+ vpm->curpage = 0x80;
+ vpm->dspid = -1;
+
+ /* Place this structure in the ifaces array so that the DspId from the
+ * Gpak Library can be used to locate it. */
+ write_lock(&ifacelock);
+ for (i=0; i<MAX_DSP_CORES; ++i) {
+ if (NULL == ifaces[i]) {
+ ifaces[i] = vpm;
+ vpm->dspid = i;
+ break;
+ }
+ }
+ write_unlock(&ifacelock);
+
+ if (-1 == vpm->dspid) {
+ kfree(vpm);
+ printk(KERN_NOTICE "Unable to initialize another vpmadt032 modules\n");
+ vpm = NULL;
+ } else if (vpm->options.debug & DEBUG_ECHOCAN) {
+ printk(KERN_DEBUG "Setting VPMADT032 DSP ID to %d\n", vpm->dspid);
+ }
+
+ return vpm;
+}
+EXPORT_SYMBOL(vpmadt032_alloc);
+
+int
+vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb)
+{
+ int i;
+ u16 reg;
+ int res = -EFAULT;
+ gpakPingDspStat_t pingstatus;
+
+ BUG_ON(!vpm->setchanconfig_from_state);
+ might_sleep();
+
+ if (vpm->options.debug & DEBUG_ECHOCAN)
+ printk(KERN_DEBUG "VPMADT032 Testing page access: ");
+
+ for (i = 0; i < 0xf; i++) {
+ int x;
+ for (x = 0; x < 3; x++) {
+ vpmadt032_setpage(vpm, i);
+ reg = vpmadt032_getpage(vpm);
+ if (reg != i) {
+ if (vpm->options.debug & DEBUG_ECHOCAN)
+ printk(KERN_DEBUG "Failed: Sent %x != %x VPMADT032 Failed HI page test\n", i, reg);
+ res = -ENODEV;
+ goto failed_exit;
+ }
+ }
+ }
+
+ if (vpm->options.debug & DEBUG_ECHOCAN)
+ printk(KERN_DEBUG "Passed\n");
+
+ set_bit(VPM150M_HPIRESET, &vpm->control);
+ msleep(2000);
+ while (test_bit(VPM150M_HPIRESET, &vpm->control))
+ msleep(1);
+
+ /* Set us up to page 0 */
+ vpmadt032_setpage(vpm, 0);
+ if (vpm->options.debug & DEBUG_ECHOCAN)
+ printk(KERN_DEBUG "VPMADT032 now doing address test: ");
+
+ for (i = 0; i < 16; i++) {
+ int x;
+ for (x = 0; x < 2; x++) {
+ vpmadt032_setreg(vpm, 0x1000, i);
+ vpmadt032_getreg(vpm, 0x1000, &reg);
+ if (reg != i) {
+ printk("VPMADT032 Failed address test\n");
+ goto failed_exit;
+ }
+
+ }
+ }
+
+ if (vpm->options.debug & DEBUG_ECHOCAN)
+ printk("Passed\n");
+
+ set_bit(VPM150M_HPIRESET, &vpm->control);
+ while (test_bit(VPM150M_HPIRESET, &vpm->control))
+ msleep(1);
+
+ res = vpmadtreg_loadfirmware(vb);
+ if (res) {
+ struct pci_dev *pdev = voicebus_get_pci_dev(vb);
+ dev_printk(KERN_INFO, &pdev->dev, "Failed to load the firmware.\n");
+ return res;
+ }
+ vpm->curpage = -1;
+ set_bit(VPM150M_SWRESET, &vpm->control);
+
+ while (test_bit(VPM150M_SWRESET, &vpm->control))
+ msleep(1);
+
+ pingstatus = gpakPingDsp(vpm->dspid, &vpm->version);
+
+ if (!pingstatus) {
+ if (vpm->options.debug & DEBUG_ECHOCAN)
+ printk(KERN_DEBUG "Version of DSP is %x\n", vpm->version);
+ } else {
+ printk(KERN_NOTICE "VPMADT032 Failed! Unable to ping the DSP (%d)!\n", pingstatus);
+ res = -1;
+ goto failed_exit;
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+ INIT_WORK(&vpm->work, vpmadt032_bh, vpm);
+#else
+ INIT_WORK(&vpm->work, vpmadt032_bh);
+#endif
+
+ return 0;
+
+failed_exit:
+ return res;
+}
+EXPORT_SYMBOL(vpmadt032_init);
+
+
+void vpmadt032_free(struct vpmadt032 *vpm)
+{
+ unsigned long flags;
+ struct vpmadt032_cmd *cmd;
+ LIST_HEAD(local_list);
+
+ BUG_ON(!vpm);
+
+ /* Move all the commands onto the local list protected by the locks */
+ spin_lock_irqsave(&vpm->list_lock, flags);
+ list_splice(&vpm->pending_cmds, &local_list);
+ list_splice(&vpm->active_cmds, &local_list);
+ list_splice(&vpm->free_cmds, &local_list);
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+
+ while (!list_empty(&local_list)) {
+ cmd = list_entry(local_list.next, struct vpmadt032_cmd, node);
+ list_del(&cmd->node);
+ kfree(cmd);
+ }
+
+ BUG_ON(ifaces[vpm->dspid] != vpm);
+ write_lock(&ifacelock);
+ ifaces[vpm->dspid] = NULL;
+ write_unlock(&ifacelock);
+ kfree(vpm);
+}
+EXPORT_SYMBOL(vpmadt032_free);
+
+int vpmadt032_module_init(void)
+{
+ rwlock_init(&ifacelock);
+ memset(ifaces, 0, sizeof(ifaces));
+ return 0;
+}
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * 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 vpmadt032 *vpm = find_iface(DspId);
+ int i;
+ int ret;
+
+ vpmadt032_io_wait(vpm);
+ if ( NumWords < VPM150M_MAX_COMMANDS ) {
+ struct vpmadt032_cmd *cmds[VPM150M_MAX_COMMANDS] = {0};
+ vpmadt032_setpage(vpm, DspAddress >> 16);
+ DspAddress &= 0xffff;
+ for (i=0; i < NumWords; ++i) {
+ if (!(cmds[i] = vpmadt032_getreg_full_async(vpm,0,DspAddress+i))) {
+ return;
+ }
+ }
+ for (i=NumWords-1; i >=0; --i) {
+ ret = vpmadt032_getreg_full_return(vpm,0,DspAddress+i,&pWordValues[i],
+ cmds[i]);
+ if (0 != ret) {
+ return;
+ }
+ }
+ }
+ else {
+ for (i=0; i<NumWords; ++i) {
+ vpmadt032_getreg(vpm, DspAddress + i, &pWordValues[i]);
+ }
+ }
+ 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 vpmadt032 *vpm = find_iface(DspId);
+ int i;
+
+ //printk(KERN_DEBUG "Writing %d words to memory\n", NumWords);
+ if (vpm) {
+ for (i = 0; i < NumWords; ++i) {
+ vpmadt032_setreg(vpm, DspAddress + i, pWordValues[i]);
+ }
+#if 0
+ for (i = 0; i < NumWords; i++) {
+ if (wctdm_vpmadt032_getreg(wc, DspAddress + i) != pWordValues[i]) {
+ printk(KERN_NOTICE "Error in write. Address %x is not %x\n", DspAddress + i, pWordValues[i]);
+ }
+ }
+#endif
+ }
+ 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 vpmadt032 *vpm;
+
+ vpm = find_iface(DspId);
+
+ 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 vpmadt032 *vpm;
+
+ vpm = find_iface(DspId);
+
+ 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 */
+ )
+{
+ /* The firmware is loaded into the part by a closed-source firmware
+ * loader, and therefore this function should never be called. */
+ WARN_ON(1);
+ return -1;
+}
diff --git a/drivers/dahdi/wctdm24xxp/GpakCust.h b/drivers/dahdi/voicebus/GpakCust.h
index f2b729f..befdabc 100644
--- a/drivers/dahdi/wctdm24xxp/GpakCust.h
+++ b/drivers/dahdi/voicebus/GpakCust.h
@@ -16,7 +16,7 @@
* 06/15/05 - Initial release.
*
* This program has been released under the terms of the GPL version 2 by
- * permission of Adaptive Digital Technologies, Inc.
+ * permission of Adaptive Digital Technologies, Inc.
*
*/
@@ -36,31 +36,120 @@
#ifndef _GPAKCUST_H /* prevent multiple inclusion */
#define _GPAKCUST_H
-#include "wctdm24xxp.h"
-#ifdef VPM150M_SUPPORT
#include <linux/device.h>
-#include <linux/firmware.h>
-#endif
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+
#include "gpakenum.h"
+#include "adt_lec.h"
+
+#define DEBUG_ECHOCAN (1 << 1)
+
+/* Host and DSP system dependent related definitions. */
+#define MAX_DSP_CORES 128 /* maximum number of DSP cores */
+#define MAX_CHANNELS 32 /* maximum number of channels */
+#define MAX_WAIT_LOOPS 50 /* max number of wait delay loops */
+#define DSP_IFBLK_ADDRESS 0x0100 /* DSP address of I/F block pointer */
+#define DOWNLOAD_BLOCK_SIZE 512 /* download block size (DSP words) */
+
+#define VPM150M_MAX_COMMANDS 8
+
+#define __VPM150M_RWPAGE (1 << 4)
+#define __VPM150M_RD (1 << 3)
+#define __VPM150M_WR (1 << 2)
+#define __VPM150M_FIN (1 << 1)
+#define __VPM150M_TX (1 << 0)
+#define __VPM150M_RWPAGE (1 << 4)
+#define __VPM150M_RD (1 << 3)
+#define __VPM150M_WR (1 << 2)
+#define __VPM150M_FIN (1 << 1)
+#define __VPM150M_TX (1 << 0)
+
+/* Some Bit ops for different operations */
+#define VPM150M_SPIRESET 0
+#define VPM150M_HPIRESET 1
+#define VPM150M_SWRESET 2
+#define VPM150M_DTMFDETECT 3
+#define VPM150M_ACTIVE 4
-struct wctdm_firmware {
- const struct firmware *fw;
- unsigned int offset;
+struct vpmadt032_cmd {
+ struct list_head node;
+ __le32 address;
+ __le16 data;
+ u8 desc;
+ u8 txident;
+ struct completion complete;
};
-/* Host and DSP system dependent related definitions. */
-#define MAX_DSP_CORES 128 /* maximum number of DSP cores */
-//#define MAX_CONFS 1 /* maximum number of conferences */
-//#define MAX_PKT_CHANNELS 8 /* maximum number of packet channels */
-#define MAX_CHANNELS 32 /* maximum number of channels */
-#define MAX_WAIT_LOOPS 50 /* max number of wait delay loops */
-#define DSP_IFBLK_ADDRESS 0x0100 /* DSP address of I/F block pointer */
-#define DOWNLOAD_BLOCK_SIZE 512 /* download block size (DSP words) */
-//#define MAX_CIDPAYLOAD_BYTES 512 /* max size of a CID payload (octets) */
-typedef unsigned short DSP_WORD; /* 16 bit DSP word */
-typedef unsigned int DSP_ADDRESS; /* 32 bit DSP address */
-typedef struct wctdm_firmware* GPAK_FILE_ID; /* G.PAK Download file identifier */
+/* Contains the options used when initializing the vpmadt032 module */
+struct vpmadt032_options {
+ int vpmnlptype;
+ int vpmnlpthresh;
+ int vpmnlpmaxsupp;
+ u32 debug;
+ u32 channels;
+};
+
+struct GpakChannelConfig;
+
+#define MAX_CHANNELS_PER_SPAN 32
+struct vpmadt032 {
+ void *context;
+ const struct dahdi_span *span;
+ struct work_struct work;
+ int dspid;
+ struct semaphore sem;
+ unsigned long control;
+ unsigned char curpage;
+ unsigned short version;
+ struct adt_lec_params curecstate[MAX_CHANNELS_PER_SPAN];
+ struct adt_lec_params desiredecstate[MAX_CHANNELS_PER_SPAN];
+ spinlock_t list_lock;
+ /* Commands that are ready to be used. */
+ struct list_head free_cmds;
+ /* Commands that are waiting to be processed. */
+ struct list_head pending_cmds;
+ /* Commands that are currently in progress by the VPM module */
+ struct list_head active_cmds;
+ unsigned char curtone[MAX_CHANNELS_PER_SPAN];
+ struct vpmadt032_options options;
+ void (*setchanconfig_from_state)(struct vpmadt032 *vpm, int channel, struct GpakChannelConfig *chanconfig);
+};
+
+struct voicebus;
+struct dahdi_echocanparams;
+struct dahdi_echocanparam;
+
+char vpmadt032tone_to_zaptone(GpakToneCodes_t tone);
+int vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb);
+struct vpmadt032 *vpmadt032_alloc(struct vpmadt032_options *options);
+void vpmadt032_free(struct vpmadt032 *vpm);
+int vpmadt032_echocan_with_params(struct vpmadt032 *vpm, int channo,
+ struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p);
+
+/* If there is a command ready to go to the VPMADT032, return it, otherwise NULL */
+static inline struct vpmadt032_cmd *vpmadt032_get_ready_cmd(struct vpmadt032 *vpm)
+{
+ unsigned long flags;
+ struct vpmadt032_cmd *cmd;
+
+ spin_lock_irqsave(&vpm->list_lock, flags);
+ if (list_empty(&vpm->pending_cmds)) {
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+ return NULL;
+ }
+ cmd = list_entry(vpm->pending_cmds.next, struct vpmadt032_cmd, node);
+ list_move_tail(&cmd->node, &vpm->active_cmds);
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+ return cmd;
+}
+
+int vpmadt032_module_init(void);
+
+typedef __u16 DSP_WORD; /* 16 bit DSP word */
+typedef __u32 DSP_ADDRESS; /* 32 bit DSP address */
+typedef __u32 GPAK_FILE_ID; /* G.PAK Download file identifier */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* gpakReadDspMemory - Read DSP memory.
@@ -74,7 +163,7 @@ typedef struct wctdm_firmware* GPAK_FILE_ID; /* G.PAK Download file identifier *
*
*/
extern void gpakReadDspMemory(
- unsigned short int DspId, /* DSP Identifier (0 to MAX_DSP_CORES-1) */
+ 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 */
@@ -129,7 +218,6 @@ extern void gpakLockAccess(
unsigned short int DspId /* DSP Identifier (0 to MAX_DSP_CORES-1) */
);
-
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* gpakUnlockAccess - Unlock access to the specified DSP.
*
@@ -144,7 +232,6 @@ extern void gpakUnlockAccess(
unsigned short int DspId /* DSP Identifier (0 to MAX_DSP_CORES-1) */
);
-
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* gpakReadFile - Read a block of bytes from a G.PAK Download file.
*
@@ -165,16 +252,6 @@ extern int gpakReadFile(
);
-unsigned char wctdm_vpm150m_getpage(struct wctdm *wc);
-
-int wctdm_vpm150m_setpage(struct wctdm *wc, unsigned short addr);
-
-int wctdm_vpm150m_setreg(struct wctdm *wc, unsigned int len, unsigned int addr, unsigned short *data);
-
-unsigned short wctdm_vpm150m_getreg(struct wctdm *wc, unsigned int len, unsigned int addr, unsigned short *data);
-
-char vpm150mtone_to_zaptone(GpakToneCodes_t tone);
-
#endif /* prevent multiple inclusion */
diff --git a/drivers/dahdi/wctdm24xxp/GpakHpi.h b/drivers/dahdi/voicebus/GpakHpi.h
index ffbf349..ffbf349 100644
--- a/drivers/dahdi/wctdm24xxp/GpakHpi.h
+++ b/drivers/dahdi/voicebus/GpakHpi.h
diff --git a/drivers/dahdi/voicebus/Kbuild b/drivers/dahdi/voicebus/Kbuild
new file mode 100644
index 0000000..7b33956
--- /dev/null
+++ b/drivers/dahdi/voicebus/Kbuild
@@ -0,0 +1,5 @@
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VOICEBUS) += dahdi_voicebus.o
+
+dahdi_voicebus-objs := voicebus.o GpakCust.o GpakApi.o
+
+EXTRA_CFLAGS := -I$(src)/.. -Wno-undef
diff --git a/drivers/dahdi/wctdm24xxp/gpakErrs.h b/drivers/dahdi/voicebus/gpakErrs.h
index c36a1b7..c36a1b7 100644
--- a/drivers/dahdi/wctdm24xxp/gpakErrs.h
+++ b/drivers/dahdi/voicebus/gpakErrs.h
diff --git a/drivers/dahdi/wctdm24xxp/gpakenum.h b/drivers/dahdi/voicebus/gpakenum.h
index f488a81..f488a81 100644
--- a/drivers/dahdi/wctdm24xxp/gpakenum.h
+++ b/drivers/dahdi/voicebus/gpakenum.h
diff --git a/drivers/dahdi/voicebus.c b/drivers/dahdi/voicebus/voicebus.c
index c67be25..d794365 100644
--- a/drivers/dahdi/voicebus.c
+++ b/drivers/dahdi/voicebus/voicebus.c
@@ -34,8 +34,12 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
+#include <linux/module.h>
+#include <dahdi/kernel.h>
#include "voicebus.h"
+#include "vpmadtreg.h"
+#include "GpakCust.h"
#define assert(__x__) BUG_ON(!(__x__))
@@ -365,6 +369,42 @@ voicebus_set_minlatency(struct voicebus *vb, unsigned int ms)
VBUNLOCK(vb);
return 0;
}
+EXPORT_SYMBOL(voicebus_set_minlatency);
+
+void
+voicebus_get_handlers(struct voicebus *vb, void **handle_receive,
+ void **handle_transmit, void **context)
+{
+ LOCKS_VOICEBUS;
+ BUG_ON(!handle_receive);
+ BUG_ON(!handle_transmit);
+ BUG_ON(!context);
+ VBLOCK(vb);
+ *handle_receive = vb->handle_receive;
+ *handle_transmit = vb->handle_transmit;
+ *context = vb->context;
+ VBUNLOCK(vb);
+ return;
+}
+EXPORT_SYMBOL(voicebus_get_handlers);
+
+void
+voicebus_set_handlers(struct voicebus *vb,
+ void (*handle_receive)(void *buffer, void *context),
+ void (*handle_transmit)(void *buffer, void *context),
+ void *context)
+{
+ LOCKS_VOICEBUS;
+ BUG_ON(!handle_receive);
+ BUG_ON(!handle_transmit);
+ BUG_ON(!context);
+ VBLOCK(vb);
+ vb->handle_receive = handle_receive;
+ vb->handle_transmit = handle_transmit;
+ vb->context = context;
+ VBUNLOCK(vb);
+}
+EXPORT_SYMBOL(voicebus_set_handlers);
/*! \brief Returns the number of buffers currently on the transmit queue. */
int
@@ -377,6 +417,7 @@ voicebus_current_latency(struct voicebus *vb)
VBUNLOCK(vb);
return latency;
}
+EXPORT_SYMBOL(voicebus_current_latency);
/*!
* \brief Read one of the hardware control registers without acquiring locks.
@@ -549,12 +590,14 @@ voicebus_setdebuglevel(struct voicebus *vb, u32 level)
{
atomic_set(&vb->debuglevel, level);
}
+EXPORT_SYMBOL(voicebus_setdebuglevel);
int
voicebus_getdebuglevel(struct voicebus *vb)
{
return atomic_read(&vb->debuglevel);
}
+EXPORT_SYMBOL(voicebus_getdebuglevel);
/*! \brief Resets the voicebus hardware interface. */
static int
@@ -732,6 +775,7 @@ voicebus_transmit(struct voicebus *vb, void *vbb)
{
return vb_submit(vb, &vb->txd, vbb);
}
+EXPORT_SYMBOL(voicebus_transmit);
/*!
* \brief Give a frame to the hardware to use for receiving.
@@ -931,6 +975,7 @@ voicebus_start(struct voicebus *vb)
return 0;
}
+EXPORT_SYMBOL(voicebus_start);
static void
vb_clear_start_transmit_bit(struct voicebus *vb)
@@ -1016,6 +1061,7 @@ voicebus_stop(struct voicebus *vb)
return 0;
}
+EXPORT_SYMBOL(voicebus_stop);
/*!
* \brief Prepare the interface for module unload.
@@ -1051,6 +1097,7 @@ voicebus_release(struct voicebus *vb)
pci_disable_device(vb->pdev);
kfree(vb);
}
+EXPORT_SYMBOL(voicebus_release);
static void
__vb_increase_latency(struct voicebus *vb)
@@ -1467,6 +1514,7 @@ cleanup:
assert(0 != retval);
return retval;
}
+EXPORT_SYMBOL(voicebus_init);
/*! \brief Return the pci_dev in use by this voicebus interface. */
@@ -1475,3 +1523,106 @@ voicebus_get_pci_dev(struct voicebus *vb)
{
return vb->pdev;
}
+EXPORT_SYMBOL(voicebus_get_pci_dev);
+
+static spinlock_t loader_list_lock;
+static struct list_head binary_loader_list;
+
+/**
+ * vpmadtreg_loadfirmware - Load the vpmadt032 firmware.
+ * @vb: The voicebus device to load.
+ */
+int vpmadtreg_loadfirmware(struct voicebus *vb)
+{
+ struct vpmadt_loader *loader;
+ int ret = 0;
+ int loader_present = 0;
+ might_sleep();
+
+ /* First check to see if a loader is already loaded into memory. */
+ spin_lock(&loader_list_lock);
+ loader_present = !(list_empty(&binary_loader_list));
+ spin_unlock(&loader_list_lock);
+
+ if (!loader_present) {
+ ret = request_module("dahdi_vpmadt032_loader");
+ if (ret)
+ return ret;
+ }
+
+ spin_lock(&loader_list_lock);
+ if (!list_empty(&binary_loader_list)) {
+ loader = list_entry(binary_loader_list.next,
+ struct vpmadt_loader, node);
+ if (try_module_get(loader->owner)) {
+ spin_unlock(&loader_list_lock);
+ ret = loader->load(vb);
+ module_put(loader->owner);
+ } else {
+ spin_unlock(&loader_list_lock);
+ printk(KERN_INFO "Failed to find a registered loader after loading module.\n");
+ ret = -ENODEV;
+ }
+ } else {
+ spin_unlock(&loader_list_lock);
+ printk(KERN_INFO "Failed to find a registered loader after loading module.\n");
+ ret = -1;
+ }
+ return ret;
+}
+
+/* Called by the binary loader module when it is ready to start loading
+ * firmware. */
+int vpmadtreg_register(struct vpmadt_loader *loader)
+{
+ spin_lock(&loader_list_lock);
+ list_add_tail(&loader->node, &binary_loader_list);
+ spin_unlock(&loader_list_lock);
+ return 0;
+}
+EXPORT_SYMBOL(vpmadtreg_register);
+
+int vpmadtreg_unregister(struct vpmadt_loader *loader)
+{
+ int removed = 0;
+ struct vpmadt_loader *cur, *temp;
+ list_for_each_entry_safe(cur, temp, &binary_loader_list, node) {
+ if (loader == cur) {
+ list_del_init(&cur->node);
+ removed = 1;
+ break;
+ }
+ }
+ WARN_ON(!removed);
+ return 0;
+}
+EXPORT_SYMBOL(vpmadtreg_unregister);
+
+int __init voicebus_module_init(void)
+{
+ int res;
+ /* This registration with dahdi.ko will fail since the span is not
+ * defined, but it will make sure that this module is a dependency of
+ * dahdi.ko, so that when it is being unloded, this module will be
+ * unloaded as well.
+ */
+ dahdi_register(0, 0);
+ INIT_LIST_HEAD(&binary_loader_list);
+ spin_lock_init(&loader_list_lock);
+ res = vpmadt032_module_init();
+ if (res)
+ return res;
+ return 0;
+}
+
+void __exit voicebus_module_cleanup(void)
+{
+ WARN_ON(!list_empty(&binary_loader_list));
+}
+
+MODULE_DESCRIPTION("Voicebus Interface w/VPMADT032 support");
+MODULE_AUTHOR("Digium Incorporated <support@digium.com>");
+MODULE_LICENSE("GPL");
+
+module_init(voicebus_module_init);
+module_exit(voicebus_module_cleanup);
diff --git a/drivers/dahdi/voicebus.h b/drivers/dahdi/voicebus/voicebus.h
index f3be573..eaa51e6 100644
--- a/drivers/dahdi/voicebus.h
+++ b/drivers/dahdi/voicebus/voicebus.h
@@ -6,7 +6,7 @@
* Matthew Fredrickson <creslin@digium.com>, and
* Michael Spiceland <mspiceland@digium.com>
*
- * Copyright (C) 2007-2008 Digium, Inc.
+ * Copyright (C) 2007-2009 Digium, Inc.
*
* All rights reserved.
*
@@ -43,6 +43,12 @@ int voicebus_init(struct pci_dev* pdev, u32 framesize,
void *context,
u32 debuglevel,
struct voicebus **vb_p);
+void voicebus_get_handlers(struct voicebus *vb, void **handle_receive,
+ void **handle_transmit, void **context);
+void voicebus_set_handlers(struct voicebus *vb,
+ void (*handle_receive)(void *buffer, void *context),
+ void (*handle_transmit)(void *buffer, void *context),
+ void *context);
void voicebus_release(struct voicebus *vb);
int voicebus_start(struct voicebus *vb);
int voicebus_stop(struct voicebus *vb);
diff --git a/drivers/dahdi/voicebus/vpmadtreg.c b/drivers/dahdi/voicebus/vpmadtreg.c
new file mode 100644
index 0000000..33390d8
--- /dev/null
+++ b/drivers/dahdi/voicebus/vpmadtreg.c
@@ -0,0 +1,29 @@
+/*
+ * vpmadtreg.c - Registration utility for firmware loaders.
+ *
+ * Allows drivers for boards that host VPMAD032 modules to initiate firmware
+ * loads.
+ *
+ * Written by Digium Incorporated <support@digium.com>
+ *
+ * Copyright (C) 2008-2009 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/spinlock.h>
+#include <linux/module.h>
+#include <linux/list.h>
+
+#include "voicebus.h"
+#include "GpakCust.h"
+#include "vpmadtreg.h"
+
diff --git a/drivers/dahdi/voicebus/vpmadtreg.h b/drivers/dahdi/voicebus/vpmadtreg.h
new file mode 100644
index 0000000..f3a5b8c
--- /dev/null
+++ b/drivers/dahdi/voicebus/vpmadtreg.h
@@ -0,0 +1,36 @@
+/*
+ * vpmadtreg.h - Registration utility for firmware loaders.
+ *
+ * Allows drivers for boards that host VPMAD032 modules to initiate firmware
+ * loads.
+ *
+ * Written by Digium Incorporated <support@digium.com>
+ *
+ * Copyright (C) 2008-2009 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.
+ */
+#ifndef __VPMADTREG_H__
+#define __VPMADTREG_H__
+
+struct vpmadt032;
+struct voicebus;
+
+struct vpmadt_loader {
+ struct module *owner;
+ struct list_head node;
+ int (*load)(struct voicebus *);
+};
+
+int vpmadtreg_register(struct vpmadt_loader *loader);
+int vpmadtreg_unregister(struct vpmadt_loader *loader);
+int vpmadtreg_loadfirmware(struct voicebus *vb);
+#endif
diff --git a/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c b/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c
new file mode 100644
index 0000000..b43ae83
--- /dev/null
+++ b/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c
@@ -0,0 +1,154 @@
+/*
+ * DAHDI Telephony Interface to VPMADT032 Firmware Loader
+ *
+ * Copyright (C) 2008-2009 Digium, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/moduleparam.h>
+#include <linux/pci.h>
+
+#include <dahdi/kernel.h>
+
+static int debug;
+
+#define module_printk(level, fmt, args...) \
+ printk(level "%s: " fmt, THIS_MODULE->name, ## args)
+#define debug_printk(level, fmt, args...) if (debug >= level) \
+ printk(KERN_DEBUG "%s (%s): " fmt, THIS_MODULE->name, \
+ __func__, ## args)
+
+#include "voicebus/voicebus.h"
+#include "voicebus/vpmadtreg.h"
+#include "vpmadt032_loader.h"
+
+vpmlinkage static int __attribute__((format (printf, 1, 2)))
+logger(const char *format, ...)
+{
+ int res;
+ va_list args;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
+ va_start(args, format);
+ res = vprintk(format, args);
+ va_end(args);
+#else
+ char buf[256];
+
+ va_start(args, format);
+ res = vsnprintf(buf, sizeof(buf), format, args);
+ va_end(args);
+ printk(KERN_INFO "%s" buf);
+#endif
+
+ return res;
+}
+
+vpmlinkage static void *memalloc(size_t len)
+{
+ return kmalloc(len, GFP_KERNEL);
+}
+
+vpmlinkage static void memfree(void *ptr)
+{
+ kfree(ptr);
+}
+
+struct private_context {
+ struct voicebus *vb;
+ void *old_rx;
+ void *old_tx;
+ void *old_context;
+ void *pvt;
+ struct completion done;
+};
+
+static void init_private_context(struct private_context *ctx)
+{
+ memset(ctx, 0, sizeof(ctx));
+ init_completion(&ctx->done);
+}
+
+static void handle_receive(void *vbb, void *context)
+{
+ struct private_context *ctx = context;
+ __vpmadt032_receive(ctx->pvt, vbb);
+ if (__vpmadt032_done(ctx->pvt))
+ complete(&ctx->done);
+}
+
+static void handle_transmit(void *vbb, void *context)
+{
+ struct private_context *ctx = context;
+ __vpmadt032_transmit(ctx->pvt, vbb);
+ voicebus_transmit(ctx->vb, vbb);
+}
+
+static int vpmadt032_load_firmware(struct voicebus *vb)
+{
+ int ret = 0;
+ struct private_context *ctx;
+ struct pci_dev *pdev = voicebus_get_pci_dev(vb);
+ might_sleep();
+ ctx = kmalloc(sizeof(struct private_context), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ init_private_context(ctx);
+ ctx->vb = vb;
+ ret = __vpmadt032_start_load(
+ 0, pdev->vendor << 16 | pdev->device,
+ &ctx->pvt);
+ if (ret)
+ goto error_exit;
+ voicebus_get_handlers(vb, &ctx->old_rx, &ctx->old_tx,
+ &ctx->old_context);
+ voicebus_set_handlers(vb, handle_receive, handle_transmit, ctx);
+ wait_for_completion(&ctx->done);
+ voicebus_set_handlers(vb, ctx->old_rx, ctx->old_tx, ctx->old_context);
+ __vpmadt032_cleanup(ctx->pvt);
+error_exit:
+ kfree(ctx);
+ return 0;
+}
+
+static struct vpmadt_loader loader = {
+ .owner = THIS_MODULE,
+ .load = vpmadt032_load_firmware,
+};
+
+static int __init vpmadt032_loader_init(void)
+{
+ __vpmadt032_init(logger, debug, memalloc, memfree);
+ vpmadtreg_register(&loader);
+ return 0;
+}
+
+static void __exit vpmadt032_loader_exit(void)
+{
+ vpmadtreg_unregister(&loader);
+ return;
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_DESCRIPTION("DAHDI VPMADT032 (Hardware Echo Canceller) Firmware Loader");
+MODULE_AUTHOR("Digium Incorporated <support@digium.com>");
+MODULE_LICENSE("Digium Commercial");
+
+module_init(vpmadt032_loader_init);
+module_exit(vpmadt032_loader_exit);
diff --git a/drivers/dahdi/wctdm24xxp/GpakApi.c b/drivers/dahdi/wctdm24xxp/GpakApi.c
deleted file mode 100644
index 1f1bb0b..0000000
--- a/drivers/dahdi/wctdm24xxp/GpakApi.c
+++ /dev/null
@@ -1,1630 +0,0 @@
-/*
- * Copyright (c) 2005, Adaptive Digital Technologies, Inc.
- *
- * File Name: GpakApi.c
- *
- * Description:
- * This file contains user API functions to communicate with DSPs executing
- * G.PAK software. The file is integrated into the host processor connected
- * to C55X G.PAK DSPs via a Host Port Interface.
- *
- * Version: 1.0
- *
- * Revision History:
- * 06/15/05 - Initial release.
- * 11/15/2006 - 24 TDM-TDM Channels EC release
- *
- * This program has been released under the terms of the GPL version 2 by
- * permission of Adaptive Digital Technologies, Inc.
- *
- */
-
-/*
- * 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/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-#include <linux/semaphore.h>
-#else
-#include <asm/semaphore.h>
-#endif
-
-#include <dahdi/kernel.h>
-
-#include "GpakHpi.h"
-#include "GpakCust.h"
-#include "GpakApi.h"
-#include "gpakenum.h"
-
-/* DSP to Host interface block offsets. */
-#define REPLY_MSG_PNTR_OFFSET 0 /* I/F blk offset to Reply Msg Pointer */
-#define CMD_MSG_PNTR_OFFSET 2 /* I/F blk offset to Command Msg Pointer */
-#define EVENT_MSG_PNTR_OFFSET 4 /* I/F blk offset to Event Msg Pointer */
-#define PKT_BUFR_MEM_OFFSET 6 /* I/F blk offset to Packet Buffer memory */
-#define DSP_STATUS_OFFSET 8 /* I/F blk offset to DSP Status */
-#define VERSION_ID_OFFSET 9 /* I/F blk offset to G.PAK Version Id */
-#define MAX_CMD_MSG_LEN_OFFSET 10 /* I/F blk offset to Max Cmd Msg Length */
-#define CMD_MSG_LEN_OFFSET 11 /* I/F blk offset to Command Msg Length */
-#define REPLY_MSG_LEN_OFFSET 12 /* I/F blk offset to Reply Msg Length */
-#define NUM_CHANNELS_OFFSET 13 /* I/F blk offset to Num Built Channels */
-#define NUM_PKT_CHANNELS_OFFSET 14 /* I/F blk offset to Num Pkt Channels */
-#define NUM_CONFERENCES_OFFSET 15 /* I/F blk offset to Num Conferences */
-//#define CPU_USAGE_OFFSET_1MS 16 /* I/F blk offset to CPU Usage statistics */
-#define CPU_USAGE_OFFSET 18 /* I/F blk offset to CPU Usage statistics */
-//#define CPU_USAGE_OFFSET_10MS 20 /* I/F blk offset to CPU Usage statistics */
-#define FRAMING_STATS_OFFSET 22 /* I/F blk offset to Framing statistics */
-
-//#define GPAK_RELEASE_Rate rate10ms
-// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
-// Macro to reconstruct a 32-bit value from two 16-bit values.
-// Parameter p32: 32-bit-wide destination
-// Parameter p16: 16-bit-wide source array of length 2 words
-#define RECONSTRUCT_LONGWORD(p32, p16) p32 = (DSP_ADDRESS)p16[0]<<16; \
- p32 |= (unsigned long)p16[1]
-// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
-
-/* DSP Status value definitions. */
-#define DSP_INIT_STATUS 0x5555 /* DSP Initialized status value */
-#define HOST_INIT_STATUS 0xAAAA /* Host Initialized status value */
-
-/* Circular packet buffer information structure offsets. */
-#define CB_BUFR_BASE 0 /* pointer to base of circular buffer */
-#define CB_BUFR_SIZE 2 /* size of buffer (words) */
-#define CB_BUFR_PUT_INDEX 3 /* offset in buffer for next write */
-#define CB_BUFR_TAKE_INDEX 4 /* offset in buffer for next read */
-#define CIRC_BUFFER_INFO_STRUCT_SIZE 6
-
-/* Miscellaneous definitions. */
-#define MSG_BUFFER_SIZE 100 /* size (words) of Host msg buffer */
-#define WORD_BUFFER_SIZE 84 /* size of DSP Word buffer (words) */
-
-#ifdef __TMS320C55XX__ // debug sections if not on host
-#pragma DATA_SECTION(pDspIfBlk,"GPAKAPIDEBUG_SECT")
-#pragma DATA_SECTION(MaxCmdMsgLen,"GPAKAPIDEBUG_SECT")
-#pragma DATA_SECTION(MaxChannels,"GPAKAPIDEBUG_SECT")
-#pragma DATA_SECTION(DlByteBufr,"GPAKAPIDEBUG_SECT")
-#pragma DATA_SECTION(DlWordBufr,"GPAKAPIDEBUG_SECT")
-#pragma DATA_SECTION(pEventFifoAddress,"GPAKAPIDEBUG_SECT")
-#endif
-
-/* Host variables related to Host to DSP interface. */
-static DSP_ADDRESS pDspIfBlk[MAX_DSP_CORES]; /* DSP address of I/F block */
-static DSP_WORD MaxCmdMsgLen[MAX_DSP_CORES]; /* max Cmd msg length (octets) */
-static unsigned short int MaxChannels[MAX_DSP_CORES]; /* max num channels */
-
-//static unsigned short int MaxPktChannels[MAX_DSP_CORES]; /* max num pkt channels */
-//static unsigned short int MaxConfs[MAX_DSP_CORES]; /* max num conferences */
-//static DSP_ADDRESS pPktInBufr[MAX_DSP_CORES][MAX_PKT_CHANNELS]; /* Pkt In buffer */
-//static DSP_ADDRESS pPktOutBufr[MAX_DSP_CORES][MAX_PKT_CHANNELS]; /* Pkt Out buffer */
-static DSP_ADDRESS pEventFifoAddress[MAX_DSP_CORES]; /* event fifo */
-
-static unsigned char DlByteBufr[DOWNLOAD_BLOCK_SIZE * 2]; /* Dowload byte buf */
-static DSP_WORD DlWordBufr[DOWNLOAD_BLOCK_SIZE]; /* Dowload word buffer */
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * CheckDspReset - Check if the DSP was reset.
- *
- * FUNCTION
- * This function determines if the DSP was reset and is ready. If reset
- * occurred, it reads interface parameters and calculates DSP addresses.
- *
- * RETURNS
- * -1 = DSP is not ready.
- * 0 = Reset did not occur.
- * 1 = Reset occurred.
- *
- */
-static int CheckDspReset(
- int DspId /* DSP Identifier (0 to MaxDSPCores-1) */
- )
-{
- DSP_ADDRESS IfBlockPntr; /* Interface Block pointer */
- DSP_WORD DspStatus; /* DSP Status */
- DSP_WORD DspChannels; /* number of DSP channels */
- DSP_WORD Temp[2];
-#if 0
- DSP_WORD DspConfs; /* number of DSP conferences */
- DSP_ADDRESS PktBufrMem; /* address of Packet Buffer */
- unsigned short int i; /* loop index / counter */
-#endif
-
- /* Read the pointer to the Interface Block. */
- gpakReadDspMemory(DspId, DSP_IFBLK_ADDRESS, 2, Temp);
- RECONSTRUCT_LONGWORD(IfBlockPntr, Temp);
-
- /* If the pointer is zero, return with an indication the DSP is not
- ready. */
- if (IfBlockPntr == 0)
- return (-1);
-
- /* Read the DSP's Status. */
- gpakReadDspMemory(DspId, IfBlockPntr + DSP_STATUS_OFFSET, 1, &DspStatus);
-
- /* If status indicates the DSP was reset, read the DSP's interface
- parameters and calculate DSP addresses. */
- if (DspStatus == DSP_INIT_STATUS ||
- ((DspStatus == HOST_INIT_STATUS) && (pDspIfBlk[DspId] == 0)))
- {
- /* Save the address of the DSP's Interface Block. */
- pDspIfBlk[DspId] = IfBlockPntr;
-
- /* Read the DSP's interface parameters. */
- gpakReadDspMemory(DspId, IfBlockPntr + MAX_CMD_MSG_LEN_OFFSET, 1,
- &(MaxCmdMsgLen[DspId]));
-
- /* read the number of configured DSP channels */
- gpakReadDspMemory(DspId, IfBlockPntr + NUM_CHANNELS_OFFSET, 1,
- &DspChannels);
- if (DspChannels > MAX_CHANNELS)
- MaxChannels[DspId] = MAX_CHANNELS;
- else
- MaxChannels[DspId] = (unsigned short int) DspChannels;
-#if 0
- /* read the number of configured DSP conferences */
- gpakReadDspMemory(DspId, IfBlockPntr + NUM_CONFERENCES_OFFSET, 1,
- &DspConfs);
- if (DspConfs > MAX_CONFS)
- MaxConfs[DspId] = MAX_CONFS;
- else
- MaxConfs[DspId] = (unsigned short int) DspConfs;
-
-
- /* read the number of configured DSP packet channels */
- gpakReadDspMemory(DspId, IfBlockPntr + NUM_PKT_CHANNELS_OFFSET, 1,
- &DspChannels);
- if (DspChannels > MAX_PKT_CHANNELS)
- MaxPktChannels[DspId] = MAX_PKT_CHANNELS;
- else
- MaxPktChannels[DspId] = (unsigned short int) DspChannels;
-
-
- /* read the pointer to the circular buffer infor struct table */
- gpakReadDspMemory(DspId, IfBlockPntr + PKT_BUFR_MEM_OFFSET, 2, Temp);
- RECONSTRUCT_LONGWORD(PktBufrMem, Temp);
-
-
- /* Determine the addresses of each channel's Packet buffers. */
- for (i = 0; i < MaxPktChannels[DspId]; i++)
- {
- pPktInBufr[DspId][i] = PktBufrMem;
- pPktOutBufr[DspId][i] = PktBufrMem + CIRC_BUFFER_INFO_STRUCT_SIZE;
- PktBufrMem += (CIRC_BUFFER_INFO_STRUCT_SIZE*2);
- }
-#endif
-
- /* read the pointer to the event fifo info struct */
- gpakReadDspMemory(DspId, IfBlockPntr + EVENT_MSG_PNTR_OFFSET, 2, Temp);
- RECONSTRUCT_LONGWORD(pEventFifoAddress[DspId], Temp);
-
- /* Set the DSP Status to indicate the host recognized the reset. */
- DspStatus = HOST_INIT_STATUS;
- gpakWriteDspMemory(DspId, IfBlockPntr + DSP_STATUS_OFFSET, 1,
- &DspStatus);
-
- /* Return with an indication that a reset occurred. */
- return (1);
- }
-
- /* If status doesn't indicate the host recognized a reset, return with an
- indication the DSP is not ready. */
- if ((DspStatus != HOST_INIT_STATUS) || (pDspIfBlk[DspId] == 0))
- return (-1);
-
- /* Return with an indication that a reset did not occur. */
- return (0);
-}
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * WriteDspCmdMessage - Write a Host Command/Request message to DSP.
- *
- * FUNCTION
- * This function writes a Host Command/Request message into DSP memory and
- * informs the DSP of the presence of the message.
- *
- * RETURNS
- * -1 = Unable to write message (msg len or DSP Id invalid or DSP not ready)
- * 0 = Temporarily unable to write message (previous Cmd Msg busy)
- * 1 = Message written successfully
- *
- */
-static int WriteDspCmdMessage(
- int DspId, /* DSP Identifier (0 to MaxDSPCores-1) */
- DSP_WORD *pMessage, /* pointer to Command message */
- DSP_WORD MsgLength /* length of message (octets) */
- )
-{
- DSP_WORD CmdMsgLength; /* current Cmd message length */
- DSP_WORD Temp[2];
- DSP_ADDRESS BufferPointer; /* message buffer pointer */
-
- /* Check if the DSP was reset and is ready. */
- if (CheckDspReset(DspId) == -1)
- return (-1);
-
- /* Make sure the message length is valid. */
- if ((MsgLength < 1) || (MsgLength > MaxCmdMsgLen[DspId]))
- return (-1);
-
- /* Make sure a previous Command message is not in use by the DSP. */
- gpakReadDspMemory(DspId, pDspIfBlk[DspId] + CMD_MSG_LEN_OFFSET, 1,
- &CmdMsgLength);
- if (CmdMsgLength != 0)
- return (0);
-
- /* Purge any previous Reply message that wasn't read. */
- gpakWriteDspMemory(DspId, pDspIfBlk[DspId] + REPLY_MSG_LEN_OFFSET, 1,
- &CmdMsgLength);
-
- /* Copy the Command message into DSP memory. */
- gpakReadDspMemory(DspId, pDspIfBlk[DspId] + CMD_MSG_PNTR_OFFSET, 2, Temp);
- RECONSTRUCT_LONGWORD(BufferPointer, Temp);
- gpakWriteDspMemory(DspId, BufferPointer, (MsgLength + 1) / 2, pMessage);
-
- /* Store the message length in DSP's Command message length (flags DSP that
- a Command message is ready). */
- CmdMsgLength = MsgLength;
- gpakWriteDspMemory(DspId, pDspIfBlk[DspId] + CMD_MSG_LEN_OFFSET, 1,
- &CmdMsgLength);
-
- /* Return with an indication the message was written. */
- return (1);
-}
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * ReadDspReplyMessage - Read a DSP Reply message from DSP.
- *
- * FUNCTION
- * This function reads a DSP Reply message from DSP memory.
- *
- * RETURNS
- * -1 = Unable to write message (msg len or DSP Id invalid or DSP not ready)
- * 0 = No message available (DSP Reply message empty)
- * 1 = Message read successfully (message and length stored in variables)
- *
- */
-static int ReadDspReplyMessage(
- int DspId, /* DSP Identifier (0 to MaxDSPCores-1) */
- DSP_WORD *pMessage, /* pointer to Reply message buffer */
- DSP_WORD *pMsgLength /* pointer to msg length var (octets) */
- )
-{
- DSP_WORD MsgLength; /* message length */
- DSP_ADDRESS BufferPointer; /* message buffer pointer */
- DSP_WORD Temp[2];
-
- /* Check if the DSP was reset and is ready. */
- if (CheckDspReset(DspId) == -1)
- return (-1);
-
- /* Check if a Reply message is ready. */
- gpakReadDspMemory(DspId, pDspIfBlk[DspId] + REPLY_MSG_LEN_OFFSET, 1,
- &MsgLength);
- if (MsgLength == 0)
- return (0);
-
- /* Make sure the message length is valid. */
- if (MsgLength > *pMsgLength)
- return (-1);
-
- /* Copy the Reply message from DSP memory. */
- gpakReadDspMemory(DspId, pDspIfBlk[DspId] + REPLY_MSG_PNTR_OFFSET, 2, Temp);
- RECONSTRUCT_LONGWORD(BufferPointer, Temp);
- gpakReadDspMemory(DspId, BufferPointer, (MsgLength + 1) / 2, pMessage);
-
- /* Store the message length in the message length variable. */
- *pMsgLength = MsgLength;
-
- /* Indicate a Reply message is not ready. */
- MsgLength = 0;
- gpakWriteDspMemory(DspId, pDspIfBlk[DspId] + REPLY_MSG_LEN_OFFSET, 1,
- &MsgLength);
-
- /* Return with an indication the message was read. */
- return (1);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * ReadCircBuffer - Read from a DSP circular buffer.
- *
- * FUNCTION
- * This function reads a block of words from a DSP circular buffer. The Take
- * address is incremented by the number of words read adjusting for buffer
- * wrap.
- *
- * RETURNS
- * nothing
- *
- */
-static void ReadCircBuffer(
- int DspId, /* DSP Identifier (0 to MaxDSPCores-1) */
- DSP_ADDRESS BufrBaseAddress, /* address of base of circular buffer */
- DSP_ADDRESS BufrLastAddress, /* address of last word in buffer */
- DSP_ADDRESS *TakeAddress, /* pointer to address in buffer for read */
- DSP_WORD *pWordBuffer, /* pointer to buffer for words read */
- DSP_WORD NumWords /* number of words to read */
- )
-{
- DSP_WORD WordsTillEnd; /* number of words until end of buffer */
-
- /* Determine the number of words from the start address until the end of the
- buffer. */
- WordsTillEnd = BufrLastAddress - *TakeAddress + 1;
-
- /* If a buffer wrap will occur, read the first part at the end of the
- buffer followed by the second part at the beginning of the buffer. */
- if (NumWords > WordsTillEnd)
- {
- gpakReadDspMemory(DspId, *TakeAddress, WordsTillEnd, pWordBuffer);
- gpakReadDspMemory(DspId, BufrBaseAddress, NumWords - WordsTillEnd,
- &(pWordBuffer[WordsTillEnd]));
- *TakeAddress = BufrBaseAddress + NumWords - WordsTillEnd;
- }
-
- /* If a buffer wrap will not occur, read all words starting at the current
- take address in the buffer. */
- else
- {
- gpakReadDspMemory(DspId, *TakeAddress, NumWords, pWordBuffer);
- if (NumWords == WordsTillEnd)
- *TakeAddress = BufrBaseAddress;
- else
- *TakeAddress = *TakeAddress + NumWords;
- }
- return;
-}
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * VerifyReply - Verify the reply message is correct for the command sent.
- *
- * FUNCTION
- * This function verifies correct reply message content for the command that
- * was just sent.
- *
- * RETURNS
- * 0 = Incorrect
- * 1 = Correct
- *
- */
-static int VerifyReply(
- DSP_WORD *pMsgBufr, /* pointer to Reply message buffer */
- int CheckType, /* reply check type */
- DSP_WORD CheckValue /* reply check value */
- )
-{
-
- /* Verify Channel or Conference Id. */
- if (CheckType == 1)
- {
- if (((pMsgBufr[1] >> 8) & 0xFF) != CheckValue)
- return (0);
- }
-
- /* Verify Test Mode Id. */
- else if (CheckType == 2)
- {
- if (pMsgBufr[1] != CheckValue)
- return (0);
- }
-
- /* Return with an indication of correct reply. */
- return (1);
-}
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * TransactCmd - Send a command to the DSP and receive it's reply.
- *
- * FUNCTION
- * This function sends the specified command to the DSP and receives the DSP's
- * reply.
- *
- * RETURNS
- * Length of reply message (0 = Failure)
- *
- */
-static unsigned int TransactCmd(
- int DspId, /* DSP Identifier (0 to MaxDSPCores-1) */
- DSP_WORD *pMsgBufr, /* pointer to Cmd/Reply message buffer */
- DSP_WORD CmdLength, /* length of command message (octets) */
- DSP_WORD ReplyType, /* required type of reply message */
- DSP_WORD ReplyLength, /* required length of reply message (octets) */
- int ReplyCheckType, /* reply check type */
- DSP_WORD ReplyCheckValue /* reply check value */
- )
-{
- int FuncStatus; /* function status */
- int LoopCount; /* wait loop counter */
- DSP_WORD RcvReplyLength; /* received Reply message length */
- DSP_WORD RcvReplyType; /* received Reply message type code */
- DSP_WORD RetValue; /* return value */
-
- /* Default the return value to indicate a failure. */
- RetValue = 0;
-
- /* Lock access to the DSP. */
- gpakLockAccess(DspId);
-
- /* Attempt to write the command message to the DSP. */
- LoopCount = 0;
- while ((FuncStatus = WriteDspCmdMessage(DspId, pMsgBufr, CmdLength)) != 1)
- {
- if (FuncStatus == -1)
- break;
- if (++LoopCount > MAX_WAIT_LOOPS)
- break;
- gpakHostDelay();
- }
-
- /* Attempt to read the reply message from the DSP if the command message was
- sent successfully. */
- if (FuncStatus == 1)
- {
- for (LoopCount = 0; LoopCount < MAX_WAIT_LOOPS; LoopCount++)
- {
- RcvReplyLength = MSG_BUFFER_SIZE * 2;
- FuncStatus = ReadDspReplyMessage(DspId, pMsgBufr, &RcvReplyLength);
- if (FuncStatus == 1)
- {
- RcvReplyType = (pMsgBufr[0] >> 8) & 0xFF;
- if ((RcvReplyLength >= ReplyLength) &&
- (RcvReplyType == ReplyType) &&
- VerifyReply(pMsgBufr, ReplyCheckType, ReplyCheckValue))
- {
- RetValue = RcvReplyLength;
- break;
- }
- else if (RcvReplyType == MSG_NULL_REPLY)
- break;
- }
- else if (FuncStatus == -1)
- break;
- gpakHostDelay();
- }
- }
-
- /* Unlock access to the DSP. */
- gpakUnlockAccess(DspId);
-
- /* Return the length of the reply message (0 = failure). */
- return (RetValue);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakConfigurePorts - Configure a DSP's serial ports.
- *
- * FUNCTION
- * This function configures a DSP's serial ports.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-gpakConfigPortStatus_t gpakConfigurePorts(
- unsigned short int DspId, /* DSP Id (0 to MaxDSPCores-1) */
- GpakPortConfig_t *pPortConfig, /* pointer to Port Config info */
- GPAK_PortConfigStat_t *pStatus /* pointer to Port Config Status */
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (CpsInvalidDsp);
-
- /* Build the Configure Serial Ports message. */
- MsgBuffer[0] = MSG_CONFIGURE_PORTS << 8;
- MsgBuffer[1] = (DSP_WORD)
- ((pPortConfig->SlotsSelect1 << 12) |
- ((pPortConfig->FirstBlockNum1 << 8) & 0x0F00) |
- ((pPortConfig->SecBlockNum1 << 4) & 0x00F0));
- MsgBuffer[2] = (DSP_WORD) pPortConfig->FirstSlotMask1;
- MsgBuffer[3] = (DSP_WORD) pPortConfig->SecSlotMask1;
- MsgBuffer[4] = (DSP_WORD)
- ((pPortConfig->SlotsSelect2 << 12) |
- ((pPortConfig->FirstBlockNum2 << 8) & 0x0F00) |
- ((pPortConfig->SecBlockNum2 << 4) & 0x00F0));
- MsgBuffer[5] = (DSP_WORD) pPortConfig->FirstSlotMask2;
- MsgBuffer[6] = (DSP_WORD) pPortConfig->SecSlotMask2;
- MsgBuffer[7] = (DSP_WORD)
- ((pPortConfig->SlotsSelect3 << 12) |
- ((pPortConfig->FirstBlockNum3 << 8) & 0x0F00) |
- ((pPortConfig->SecBlockNum3 << 4) & 0x00F0));
- MsgBuffer[8] = (DSP_WORD) pPortConfig->FirstSlotMask3;
- MsgBuffer[9] = (DSP_WORD) pPortConfig->SecSlotMask3;
-
- MsgBuffer[10] = (DSP_WORD)
- (((pPortConfig->DxDelay1 << 11) & 0x0800) |
- ((pPortConfig->RxDataDelay1 << 9) & 0x0600) |
- ((pPortConfig->TxDataDelay1 << 7) & 0x0180) |
- ((pPortConfig->RxClockPolarity1 << 6) & 0x0040) |
- ((pPortConfig->TxClockPolarity1 << 5) & 0x0020) |
- ((pPortConfig->RxFrameSyncPolarity1 << 4) & 0x0010) |
- ((pPortConfig->TxFrameSyncPolarity1 << 3) & 0x0008) |
- ((pPortConfig->CompandingMode1 << 1) & 0x0006) |
- (pPortConfig->SerialWordSize1 & 0x0001));
-
- MsgBuffer[11] = (DSP_WORD)
- (((pPortConfig->DxDelay2 << 11) & 0x0800) |
- ((pPortConfig->RxDataDelay2 << 9) & 0x0600) |
- ((pPortConfig->TxDataDelay2 << 7) & 0x0180) |
- ((pPortConfig->RxClockPolarity2 << 6) & 0x0040) |
- ((pPortConfig->TxClockPolarity2 << 5) & 0x0020) |
- ((pPortConfig->RxFrameSyncPolarity2 << 4) & 0x0010) |
- ((pPortConfig->TxFrameSyncPolarity2 << 3) & 0x0008) |
- ((pPortConfig->CompandingMode2 << 1) & 0x0006) |
- (pPortConfig->SerialWordSize1 & 0x0001));
-
- MsgBuffer[12] = (DSP_WORD)
- (((pPortConfig->DxDelay3 << 11) & 0x0800) |
- ((pPortConfig->RxDataDelay3 << 9) & 0x0600) |
- ((pPortConfig->TxDataDelay3 << 7) & 0x0180) |
- ((pPortConfig->RxClockPolarity3 << 6) & 0x0040) |
- ((pPortConfig->TxClockPolarity3 << 5) & 0x0020) |
- ((pPortConfig->RxFrameSyncPolarity3 << 4) & 0x0010) |
- ((pPortConfig->TxFrameSyncPolarity3 << 3) & 0x0008) |
- ((pPortConfig->CompandingMode3 << 1) & 0x0006) |
- (pPortConfig->SerialWordSize3 & 0x0001));
-
- MsgBuffer[13] = (DSP_WORD) pPortConfig->ThirdSlotMask1;
- MsgBuffer[14] = (DSP_WORD) pPortConfig->FouthSlotMask1;
- MsgBuffer[15] = (DSP_WORD) pPortConfig->FifthSlotMask1;
- MsgBuffer[16] = (DSP_WORD) pPortConfig->SixthSlotMask1;
- MsgBuffer[17] = (DSP_WORD) pPortConfig->SevenSlotMask1;
- MsgBuffer[18] = (DSP_WORD) pPortConfig->EightSlotMask1;
-
- MsgBuffer[19] = (DSP_WORD) pPortConfig->ThirdSlotMask2;;
- MsgBuffer[20] = (DSP_WORD) pPortConfig->FouthSlotMask2;
- MsgBuffer[21] = (DSP_WORD) pPortConfig->FifthSlotMask2;;
- MsgBuffer[22] = (DSP_WORD) pPortConfig->SixthSlotMask2;
- MsgBuffer[23] = (DSP_WORD) pPortConfig->SevenSlotMask2;;
- MsgBuffer[24] = (DSP_WORD) pPortConfig->EightSlotMask2;
-
- MsgBuffer[25] = (DSP_WORD) pPortConfig->ThirdSlotMask3;;
- MsgBuffer[26] = (DSP_WORD) pPortConfig->FouthSlotMask3;
- MsgBuffer[27] = (DSP_WORD) pPortConfig->FifthSlotMask3;;
- MsgBuffer[28] = (DSP_WORD) pPortConfig->SixthSlotMask3;
- MsgBuffer[29] = (DSP_WORD) pPortConfig->SevenSlotMask3;;
- MsgBuffer[30] = (DSP_WORD) pPortConfig->EightSlotMask3;
-
-
- /* Attempt to send the Configure Serial Ports message to the DSP and receive
- it's reply. */
- if (!TransactCmd(DspId, MsgBuffer, 62, MSG_CONFIG_PORTS_REPLY, 4, 0, 0))
- return (CpsDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- *pStatus = (GPAK_PortConfigStat_t) (MsgBuffer[1] & 0xFF);
- if (*pStatus == Pc_Success)
- return (CpsSuccess);
- else
- return (CpsParmError);
-}
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakConfigureChannel - Configure a DSP's Channel.
- *
- * FUNCTION
- * This function configures a DSP's Channel.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-gpakConfigChanStatus_t gpakConfigureChannel(
- unsigned short int DspId, /* DSP Id (0 to MaxDSPCores-1) */
- unsigned short int ChannelId, /* Channel Id (0 to MaxChannels-1) */
- GpakChanType ChannelType, /* Channel Type */
- GpakChannelConfig_t *pChanConfig, /* pointer to Channel Config info */
- GPAK_ChannelConfigStat_t *pStatus /* pointer to Channel Config Status */
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
- DSP_WORD MsgLength; /* message length */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (CcsInvalidDsp);
-
- /* Make sure the Channel Id is valid. */
- if (ChannelId >= MaxChannels[DspId])
- return (CcsInvalidChannel);
-
- /* Build the Configure Channel message based on the Channel Type. */
- switch (ChannelType)
- {
-
- /* PCM to Packet channel type. */
- case tdmToTdm:
-
- MsgBuffer[2] = (DSP_WORD)
- ((pChanConfig->PcmInPortA << 8) |
- (pChanConfig->PcmInSlotA & 0xFF));
- MsgBuffer[3] = (DSP_WORD)
- ((pChanConfig->PcmOutPortA << 8) |
- (pChanConfig->PcmOutSlotA & 0xFF));
-
- MsgBuffer[4] = (DSP_WORD)
- ((pChanConfig->PcmInPortB << 8) |
- (pChanConfig->PcmInSlotB & 0xFF));
- MsgBuffer[5] = (DSP_WORD)
- ((pChanConfig->PcmOutPortB << 8) |
- (pChanConfig->PcmOutSlotB & 0xFF));
-
- MsgBuffer[6] = (DSP_WORD)
- (
- ((pChanConfig->FaxCngDetB <<11) & 0x0800) |
- ((pChanConfig->FaxCngDetA <<10) & 0x0400) |
- ((pChanConfig->MuteToneB << 9) & 0x0200) |
- ((pChanConfig->MuteToneA << 8) & 0x0100) |
- ((pChanConfig->FrameRate << 6) & 0x00C0) |
- ((pChanConfig->ToneTypesB << 5) & 0x0020) |
- ((pChanConfig->ToneTypesA << 4) & 0x0010) |
- ((pChanConfig->SoftwareCompand & 3) << 2) |
- (pChanConfig->EcanEnableB << 1) |
- (pChanConfig->EcanEnableA & 1)
- );
-
- MsgBuffer[7] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanTapLength;
- MsgBuffer[8] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanNlpType;
- MsgBuffer[9] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanAdaptEnable;
- MsgBuffer[10] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanG165DetEnable;
- MsgBuffer[11] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanDblTalkThresh;
- MsgBuffer[12] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanNlpThreshold;
- MsgBuffer[13] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanNlpConv;
- MsgBuffer[14] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanNlpUnConv;
- MsgBuffer[15] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanNlpMaxSuppress;
-
- MsgBuffer[16] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanCngThreshold;
- MsgBuffer[17] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanAdaptLimit;
- MsgBuffer[18] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanCrossCorrLimit;
- MsgBuffer[19] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanNumFirSegments;
- MsgBuffer[20] = (DSP_WORD)
- pChanConfig->EcanParametersA.EcanFirSegmentLen;
-
- MsgBuffer[21] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanTapLength;
- MsgBuffer[22] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanNlpType;
- MsgBuffer[23] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanAdaptEnable;
- MsgBuffer[24] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanG165DetEnable;
- MsgBuffer[25] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanDblTalkThresh;
- MsgBuffer[26] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanNlpThreshold;
- MsgBuffer[27] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanNlpConv;
- MsgBuffer[28] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanNlpUnConv;
- MsgBuffer[29] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanNlpMaxSuppress;
- MsgBuffer[30] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanCngThreshold;
- MsgBuffer[31] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanAdaptLimit;
- MsgBuffer[32] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanCrossCorrLimit;
- MsgBuffer[33] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanNumFirSegments;
- MsgBuffer[34] = (DSP_WORD)
- pChanConfig->EcanParametersB.EcanFirSegmentLen;
-
- MsgLength = 70; // byte number == 35*2
- break;
-
-
- /* Unknown (invalid) channel type. */
- default:
- *pStatus = Cc_InvalidChannelType;
- return (CcsParmError);
- }
-
- MsgBuffer[0] = MSG_CONFIGURE_CHANNEL << 8;
- MsgBuffer[1] = (DSP_WORD) ((ChannelId << 8) | (ChannelType & 0xFF));
-
- /* Attempt to send the Configure Channel message to the DSP and receive it's
- reply. */
- if (!TransactCmd(DspId, MsgBuffer, MsgLength, MSG_CONFIG_CHAN_REPLY, 4, 1,
- (DSP_WORD) ChannelId))
- return (CcsDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- *pStatus = (GPAK_ChannelConfigStat_t) (MsgBuffer[1] & 0xFF);
- if (*pStatus == Cc_Success)
- return (CcsSuccess);
- else
- return (CcsParmError);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakTearDownChannel - Tear Down a DSP's Channel.
- *
- * FUNCTION
- * This function tears down a DSP's Channel.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-gpakTearDownStatus_t gpakTearDownChannel(
- unsigned short int DspId, /* DSP Id (0 to MaxDSPCores-1) */
- unsigned short int ChannelId, /* Channel Id (0 to MaxChannels-1) */
- GPAK_TearDownChanStat_t *pStatus /* pointer to Tear Down Status */
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (TdsInvalidDsp);
-
- /* Make sure the Channel Id is valid. */
- if (ChannelId >= MaxChannels[DspId])
- return (TdsInvalidChannel);
-
- /* Build the Tear Down Channel message. */
- MsgBuffer[0] = MSG_TEAR_DOWN_CHANNEL << 8;
- MsgBuffer[1] = (DSP_WORD) (ChannelId << 8);
-
- /* Attempt to send the Tear Down Channel message to the DSP and receive it's
- reply. */
- if (!TransactCmd(DspId, MsgBuffer, 3, MSG_TEAR_DOWN_REPLY, 4, 1,
- (DSP_WORD) ChannelId))
- return (TdsDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- *pStatus = (GPAK_TearDownChanStat_t) (MsgBuffer[1] & 0xFF);
- if (*pStatus == Td_Success)
- return (TdsSuccess);
- else
- return (TdsError);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakAlgControl - Control an Algorithm.
- *
- * FUNCTION
- * This function controls an Algorithm
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-gpakAlgControlStat_t gpakAlgControl(
- unsigned short int DspId, // DSP identifier
- unsigned short int ChannelId, // channel identifier
- GpakAlgCtrl_t ControlCode, // algorithm control code
- GPAK_AlgControlStat_t *pStatus // pointer to return status
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (AcInvalidDsp);
-
- /* Make sure the Channel Id is valid. */
- if (ChannelId >= MaxChannels[DspId])
- return (AcInvalidChannel);
-
- MsgBuffer[0] = MSG_ALG_CONTROL << 8;
- MsgBuffer[1] = (DSP_WORD) ((ChannelId << 8) | (ControlCode & 0xFF));
-
- /* Attempt to send the Tear Down Channel message to the DSP and receive it's
- reply. */
- //need_reply_len;
- if (!TransactCmd(DspId, MsgBuffer, 4, MSG_ALG_CONTROL_REPLY, 4, 1,
- (DSP_WORD) ChannelId))
- return (AcDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- *pStatus = (GPAK_AlgControlStat_t) (MsgBuffer[1] & 0xFF);
- if (*pStatus == Ac_Success)
- return (AcSuccess);
- else
- return (AcParmError);
-
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakReadEventFIFOMessage - read from the event fifo
- *
- * FUNCTION
- * This function reads a single event from the event fifo if one is available
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- * Notes: This function should be called in a loop until the return status
- * indicates that the fifo is empty.
- *
- * If the event code equals "EventLoopbackTeardownComplete", then the
- * contents of *pChannelId hold the coderBlockId that was assigned to
- * the loopback coder that was torn down.
- */
-gpakReadEventFIFOMessageStat_t gpakReadEventFIFOMessage(
- unsigned short int DspId, // DSP identifier
- unsigned short int *pChannelId, // pointer to channel identifier
- GpakAsyncEventCode_t *pEventCode, // pointer to Event Code
- GpakAsyncEventData_t *pEventData // pointer to Event Data Struct
- )
-{
- DSP_WORD WordBuffer[WORD_BUFFER_SIZE]; /* DSP words buffer */
- GpakAsyncEventCode_t EventCode; /* DSP's event code */
- DSP_WORD EventDataLength; /* Length of event to read */
- DSP_WORD ChannelId; /* DSP's channel Id */
- DSP_ADDRESS EventInfoAddress; /* address of EventFIFO info structure */
- DSP_ADDRESS BufrBaseAddress; /* base address of EventFIFO buffer */
- DSP_ADDRESS BufrLastAddress; /* last address of EventFIFO buffer */
- DSP_ADDRESS TakeAddress; /* current take address in fifo buffer */
- DSP_WORD BufrSize; /* size (in words) of event FIFO buffer */
- DSP_WORD PutIndex; /* event fifo put index */
- DSP_WORD TakeIndex; /* event fifo take index */
- DSP_WORD WordsReady; /* number words ready for read out of event fifo */
- DSP_WORD EventError; /* flag indicating error with event fifo msg */
-#if 0
- DSP_WORD *pDebugData; /* debug data buffer pointer in event data struct */
-#endif
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (RefInvalidDsp);
-
- /* Lock access to the DSP. */
- gpakLockAccess(DspId);
-
- /* Check if the DSP was reset and is ready. */
- if (CheckDspReset(DspId) == -1)
- {
- gpakUnlockAccess(DspId);
- return (RefDspCommFailure);
- }
-
- /* Check if an event message is ready in the DSP. */
- EventInfoAddress = pEventFifoAddress[DspId];
- gpakReadDspMemory(DspId, EventInfoAddress, CIRC_BUFFER_INFO_STRUCT_SIZE,
- WordBuffer);
- RECONSTRUCT_LONGWORD(BufrBaseAddress, ((DSP_WORD *)&WordBuffer[CB_BUFR_BASE]));
- BufrSize = WordBuffer[CB_BUFR_SIZE];
- PutIndex = WordBuffer[CB_BUFR_PUT_INDEX];
- TakeIndex = WordBuffer[CB_BUFR_TAKE_INDEX];
- if (PutIndex >= TakeIndex)
- WordsReady = PutIndex - TakeIndex;
- else
- WordsReady = PutIndex + BufrSize - TakeIndex;
-
- if (WordsReady < 2)
- {
- gpakUnlockAccess(DspId);
- return (RefNoEventAvail);
- }
-
- /* Read the event header from the DSP's Event FIFO. */
- TakeAddress = BufrBaseAddress + TakeIndex;
- BufrLastAddress = BufrBaseAddress + BufrSize - 1;
- ReadCircBuffer(DspId, BufrBaseAddress, BufrLastAddress, &TakeAddress,
- WordBuffer, 2);
- TakeIndex += 2;
- if (TakeIndex >= BufrSize)
- TakeIndex -= BufrSize;
-
- ChannelId = (WordBuffer[0] >> 8) & 0xFF;
- EventCode = (GpakAsyncEventCode_t)(WordBuffer[0] & 0xFF);
- EventDataLength = WordBuffer[1];
- EventError = 0;
-
- switch (EventCode)
- {
- case EventToneDetect:
- if (EventDataLength > WORD_BUFFER_SIZE)
- {
- gpakUnlockAccess(DspId);
-#if 0
- printk(KERN_DEBUG "EventDataLength > WORD_BUFFER_SIZE (%d)\n", EventDataLength);
-#endif
- return (RefInvalidEvent);
- }
- ReadCircBuffer(DspId, BufrBaseAddress, BufrLastAddress, &TakeAddress,
- WordBuffer, EventDataLength);
- pEventData->toneEvent.ToneCode = (GpakToneCodes_t)
- (WordBuffer[0] & 0xFF);
- pEventData->toneEvent.ToneDuration = WordBuffer[1];
- pEventData->toneEvent.Direction = WordBuffer[2];
- pEventData->toneEvent.DebugToneStatus = WordBuffer[3];
- TakeIndex += EventDataLength;
- if (TakeIndex >= BufrSize)
- TakeIndex -= BufrSize;
- if (EventDataLength != 4) {
-#if 0
- printk(KERN_DEBUG "EventDataLength != 4 it's %d\n", EventDataLength);
-#endif
- EventError = 1;
- }
- break;
-
- default:
-#if 0
- printk(KERN_DEBUG "Event Code not in switch\n");
-#endif
- EventError = 1;
- break;
- };
-
- /* Update the Take index in the DSP's Packet Out buffer information. */
- gpakWriteDspMemory(DspId, EventInfoAddress + CB_BUFR_TAKE_INDEX, 1,
- &TakeIndex);
-
- /* Unlock access to the DSP. */
- gpakUnlockAccess(DspId);
-
- if (EventError)
- return(RefInvalidEvent);
-
- *pChannelId = ChannelId;
- *pEventCode = EventCode;
- return(RefEventAvail);
-
-}
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakPingDsp - ping the DSP to see if it's alive
- *
- * FUNCTION
- * This function checks if the DSP is still communicating with the host
- * and returns the DSP SW version
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-gpakPingDspStat_t gpakPingDsp(
- unsigned short int DspId, // DSP identifier
- unsigned short int *pDspSwVersion // DSP software version
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
- DSP_WORD DspStatus; /* DSP's reply status */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (PngInvalidDsp);
-
- /* send value of 1, DSP increments it */
- MsgBuffer[0] = (MSG_PING << 8);
-
- /* Attempt to send the ping message to the DSP and receive it's
- reply. */
- if (!TransactCmd(DspId, MsgBuffer, 1, MSG_PING_REPLY, 6, 0, 0))
- return (PngDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- DspStatus = (MsgBuffer[1] & 0xFF);
- if (DspStatus == 0)
- {
- *pDspSwVersion = MsgBuffer[2];
- return (PngSuccess);
- }
- else
- return (PngDspCommFailure);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakSerialTxFixedValue - transmit a fixed value on a timeslot
- *
- * FUNCTION
- * This function controls transmission of a fixed value out onto a serial
- * port's timeslot.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-gpakSerialTxFixedValueStat_t gpakSerialTxFixedValue(
- unsigned short int DspId, // DSP identifier
- unsigned short int ChannelId, // channel identifier
- GpakSerialPort_t PcmOutPort, // PCM Output Serial Port Id
- unsigned short int PcmOutSlot, // PCM Output Time Slot
- unsigned short int Value, // 16-bit value
- GpakActivation State // activation state
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
- DSP_WORD DspStatus; /* DSP's reply status */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (TfvInvalidDsp);
-
- /* Make sure the Channel Id is valid. */
- if (ChannelId >= MaxChannels[DspId])
- return (TfvInvalidChannel);
-
-
- /* Build the message. */
- MsgBuffer[0] = MSG_SERIAL_TXVAL << 8;
- MsgBuffer[1] = (DSP_WORD) ((ChannelId << 8) | (State & 0xFF));
- MsgBuffer[2] = (DSP_WORD) ((PcmOutPort << 8) | (PcmOutSlot & 0xFF));
- MsgBuffer[3] = (DSP_WORD) Value;
-
- /* Attempt to send the message to the DSP and receive it's
- reply. */
- //need_reply_len;
- if (!TransactCmd(DspId, MsgBuffer, 8, MSG_SERIAL_TXVAL_REPLY, 4,
- 1, ChannelId))
- return (TfvDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- DspStatus = (MsgBuffer[1] & 0xFF);
- if (DspStatus == 0)
- return (TfvSuccess);
- else
- return (TfvDspCommFailure);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakControlTdmLoopBack - control a serial port's loopback state
- *
- * FUNCTION
- * This function enables/disables the tdm input to output looback mode on a
- * serial port
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-gpakControlTdmLoopBackStat_t gpakControlTdmLoopBack(
- unsigned short int DspId, // DSP identifier
- GpakSerialPort_t SerialPort, // Serial Port Id
- GpakActivation LoopBackState // Loopback State
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
- DSP_WORD DspStatus; /* DSP's reply status */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (ClbInvalidDsp);
-
- /* Build the message. */
- MsgBuffer[0] = MSG_TDM_LOOPBACK << 8;
- MsgBuffer[1] = (DSP_WORD) ((SerialPort << 8) | (LoopBackState & 0xFF));
-
- /* Attempt to send the message to the DSP and receive it's
- reply. */
- //need_reply_len;
- if (!TransactCmd(DspId, MsgBuffer, 4, MSG_TDM_LOOPBACK_REPLY, 4, 0, 0))
- return (ClbDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- DspStatus = (MsgBuffer[1] & 0xFF);
- if (DspStatus == 0)
- return (ClbSuccess);
- else
- return (ClbDspCommFailure);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakReadCpuUsage - Read CPU usage statistics from a DSP.
- *
- * FUNCTION
- * This function reads the CPU usage statistics from a DSP's memory. The
- * average CPU usage in units of .1 percent are obtained for each of the frame
- * rates.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-gpakReadCpuUsageStat_t gpakReadCpuUsage(
- unsigned short int DspId, // Dsp Identifier
- unsigned short int *pPeakUsage, // pointer to peak usage variable
- unsigned short int *pPrev1SecPeakUsage // peak usage over previous 1 second
- )
-{
- DSP_WORD ReadBuffer[2]; /* DSP read buffer */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (RcuInvalidDsp);
-
- /* Lock access to the DSP. */
- gpakLockAccess(DspId);
-
- /* Check if the DSP was reset and is ready. */
- if (CheckDspReset(DspId) == -1)
- return (RcuDspCommFailure);
-
- /* Read the CPU Usage statistics from the DSP. */
- gpakReadDspMemory(DspId, pDspIfBlk[DspId] + CPU_USAGE_OFFSET, 2,
- ReadBuffer);
-
- /* Unlock access to the DSP. */
- gpakUnlockAccess(DspId);
-
- /* Store the usage statistics in the specified variables. */
- *pPrev1SecPeakUsage = ReadBuffer[0];
- *pPeakUsage = ReadBuffer[1];
-
- /* Return with an indication the usage staistics were read successfully. */
- return (RcuSuccess);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakResetCpuUsageStats - reset the cpu usage statistics
- *
- * FUNCTION
- * This function resets the cpu utilization statistics
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-gpakResetCpuUsageStat_t gpakResetCpuUsageStats(
- unsigned short int DspId // DSP identifier
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
- DSP_WORD DspStatus; /* DSP's reply status */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (RstcInvalidDsp);
-
- MsgBuffer[0] = (MSG_RESET_USAGE_STATS << 8);
-
- /* Attempt to send the message to the DSP and receive it's reply. */
- //need_reply_len;
- if (!TransactCmd(DspId, MsgBuffer, 2, MSG_RESET_USAGE_STATS_REPLY, 4, 0, 0))
- return (RstcDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- DspStatus = (MsgBuffer[1] & 0xFF);
- if (DspStatus == 0)
- return (RstcSuccess);
- else
- return (RstcDspCommFailure);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakReadFramingStats
- *
- * FUNCTION
- * This function reads a DSP's framing interrupt statistics
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-gpakReadFramingStatsStatus_t gpakReadFramingStats(
- unsigned short int DspId, // DSP identifier
- unsigned short int *pFramingError1Count, // port 1 Framing error count
- unsigned short int *pFramingError2Count, // port 2 Framing error count
- unsigned short int *pFramingError3Count, // port 3 Framing error count
- unsigned short int *pDmaStopErrorCount, // DMA-stoppage error count
- unsigned short int *pDmaSlipStatsBuffer // DMA slips count
- )
-{
- DSP_WORD ReadBuffer[10]; /* DSP read buffer */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (RfsInvalidDsp);
-
- /* Lock access to the DSP. */
- gpakLockAccess(DspId);
-
- /* Check if the DSP was reset and is ready. */
- if (CheckDspReset(DspId) == -1)
- return (RfsDspCommFailure);
-
- /* Read the framing interrupt statistics from the DSP. */
- gpakReadDspMemory(DspId, pDspIfBlk[DspId] + FRAMING_STATS_OFFSET, 10,
- ReadBuffer);
-
- /* Unlock access to the DSP. */
- gpakUnlockAccess(DspId);
-
- /* Store the framing statistics in the specified variables. */
- *pFramingError1Count = ReadBuffer[0];
- *pFramingError2Count = ReadBuffer[1];
- *pFramingError3Count = ReadBuffer[2];
- *pDmaStopErrorCount = ReadBuffer[3];
-
- if(pDmaSlipStatsBuffer != NULL)
- // If users want to get the DMA slips count
- {
- pDmaSlipStatsBuffer[0] = ReadBuffer[4];
- pDmaSlipStatsBuffer[1] = ReadBuffer[5];
- pDmaSlipStatsBuffer[2] = ReadBuffer[6];
- pDmaSlipStatsBuffer[3] = ReadBuffer[7];
- pDmaSlipStatsBuffer[4] = ReadBuffer[8];
- pDmaSlipStatsBuffer[5] = ReadBuffer[9];
-
- }
- /* Return with an indication the statistics were read successfully. */
- return (RfsSuccess);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakResetFramingStats - reset a DSP's framing interrupt statistics
- *
- * FUNCTION
- * This function resets a DSP's framing interrupt statistics
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-gpakResetFramingStatsStatus_t gpakResetFramingStats(
- unsigned short int DspId // DSP identifier
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
- DSP_WORD DspStatus; /* DSP's reply status */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (RstfInvalidDsp);
-
- MsgBuffer[0] = (MSG_RESET_FRAME_STATS << 8);
-
- /* Attempt to send the message to the DSP and receive it's reply. */
- //need_reply_len;
- if (!TransactCmd(DspId, MsgBuffer, 2, MSG_RESET_FRAME_STATS_REPLY, 4, 0, 0))
- return (RstfDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- DspStatus = (MsgBuffer[1] & 0xFF);
- if (DspStatus == 0)
- return (RstfSuccess);
- else
- return (RstfDspCommFailure);
-}
-
-/*
- * gpakDownloadDsp - Download a DSP's Program and initialized Data memory.
- *
- * FUNCTION
- * This function reads a DSP's Program and Data memory image from the
- * specified file and writes the image to the DSP's memory.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-gpakDownloadStatus_t gpakDownloadDsp(
- unsigned short DspId, /* DSP Identifier (0 to MaxDSPCores-1) */
- GPAK_FILE_ID FileId /* G.PAK Download File Identifier */
- )
-{
- gpakDownloadStatus_t RetStatus; /* function return status */
- int NumRead; /* number of file bytes read */
- DSP_ADDRESS Address; /* DSP address */
- unsigned int WordCount; /* number of words in record */
- unsigned int NumWords; /* number of words to read/write */
- unsigned int i; /* loop index / counter */
- unsigned int j; /* loop index */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (GdlInvalidDsp);
-
- /* Lock access to the DSP. */
- gpakLockAccess(DspId);
-
- RetStatus = GdlSuccess;
- while (RetStatus == GdlSuccess)
- {
-
- /* Read a record header from the file. */
- NumRead = gpakReadFile(FileId, DlByteBufr, 6);
- if (NumRead == -1)
- {
- RetStatus = GdlFileReadError;
- break;
- }
- if (NumRead != 6)
- {
- RetStatus = GdlInvalidFile;
- break;
- }
- Address = (((DSP_ADDRESS) DlByteBufr[1]) << 16) |
- (((DSP_ADDRESS) DlByteBufr[2]) << 8) |
- ((DSP_ADDRESS) DlByteBufr[3]);
- WordCount = (((unsigned int) DlByteBufr[4]) << 8) |
- ((unsigned int) DlByteBufr[5]);
-
- /* Check for the End Of File record. */
- if (DlByteBufr[0] == 0xFF)
- break;
-
- /* Verify the record is for a valid memory type. */
- if ((DlByteBufr[0] != 0x00) && (DlByteBufr[0] != 0x01))
- {
- RetStatus = GdlInvalidFile;
- break;
- }
-
- /* Read a block of words at a time from the file and write to the
- DSP's memory .*/
- while (WordCount != 0)
- {
- if (WordCount < DOWNLOAD_BLOCK_SIZE)
- NumWords = WordCount;
- else
- NumWords = DOWNLOAD_BLOCK_SIZE;
- WordCount -= NumWords;
- NumRead = gpakReadFile(FileId, DlByteBufr, NumWords * 2);
- if (NumRead == -1)
- {
- RetStatus = GdlFileReadError;
- break;
- }
- if (NumRead != (NumWords * 2))
- {
- RetStatus = GdlInvalidFile;
- break;
- }
- for (i = 0, j = 0; i < NumWords; i++, j += 2)
- DlWordBufr[i] = (((DSP_WORD) DlByteBufr[j]) << 8) |
- ((DSP_WORD) DlByteBufr[j + 1]);
- gpakWriteDspMemory(DspId, Address, NumWords, DlWordBufr);
- Address += ((DSP_ADDRESS) NumWords);
- }
- }
-
- /* Unlock access to the DSP. */
- gpakUnlockAccess(DspId);
-
- /* Return with an indication of success or failure. */
- return (RetStatus);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakReadCpuUsage - Read CPU usage statistics from a DSP.
- *
- * FUNCTION
- * This function reads the memory map register section of DSP memory.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-gpakReadDSPMemoryStat_t gpakReadDSPMemoryMap(
- unsigned short int DspId, // Dsp Identifier
- unsigned short int *pDest, // Buffer on host to hold DSP memory map
- DSP_ADDRESS BufrBaseAddress, // DSP memory users want to read out
- unsigned short int MemoryLength_Word16 // Length of memory section read out, unit is 16-bit word
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
- DSP_WORD DspStatus; /* DSP reply's status */
- int i; /* loop index / counter */
-
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (RmmInvalidDsp);
-
- /* Verify the message buffer is large enough */
- if (MSG_BUFFER_SIZE < MemoryLength_Word16 )
- return (RmmSizeTooBig);
-
- MsgBuffer[0] = MSG_READ_DSP_MEMORY << 8;
- MsgBuffer[1] = (DSP_WORD) ((BufrBaseAddress >> 16) & 0xFFFF);
- MsgBuffer[2] = (DSP_WORD) (BufrBaseAddress & 0xFFFF);
- MsgBuffer[3] = (DSP_WORD) MemoryLength_Word16;
-
- /* Attempt to send the Read memory section message to the DSP and receive it's
- reply. */
- //need_reply_len;
- if (!TransactCmd(DspId, MsgBuffer, 8, MSG_READ_DSP_MEMORY_REPLY,
- (MemoryLength_Word16+2)*2, 0, 0) )
- return (RmmInvalidAddress);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- DspStatus = (MsgBuffer[1] & 0xFF);
- if (DspStatus != 0)
- return (RmmFailure);
-
- for (i = 0; i < MemoryLength_Word16; i++)
- pDest[i] = (short int) MsgBuffer[2 + i];
-
-
- return (RmmSuccess);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakAccessGPIO - change Direction/read/write the GPIO on DSP
- *
- * FUNCTION
- * This function read/write GPIO and change the GPIO direction
- *
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-gpakAccessGPIOStat_t gpakAccessGPIO(
- unsigned short int DspId, // DSP identifier
- GpakGPIOCotrol_t gpakControlGPIO,// select oeration, changeDIR/write/read
- unsigned short int *pGPIOValue // DSP software version
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
- DSP_WORD DspStatus; /* DSP's reply status */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (GPIOInvalidDsp);
-
- /* send value of 1, DSP increments it */
- MsgBuffer[0] = (MSG_ACCESSGPIO << 8);
- MsgBuffer[1] = (DSP_WORD) ((gpakControlGPIO << 8) | (*pGPIOValue & 0xFF) );
- /* Attempt to send the ping message to the DSP and receive it's
- reply. */
- if (!TransactCmd(DspId, MsgBuffer, 4, MSG_ACCESSGPIO_REPLY, 6, 0, 0))
- return (GPIODspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- DspStatus = (MsgBuffer[1] & 0xFF);
- if (DspStatus == 0)
- {
- *pGPIOValue = MsgBuffer[2];
- return (GPIOSuccess);
- }
- else
- return (GPIODspCommFailure);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakWriteSystemParms - Write a DSP's System Parameters.
- *
- * FUNCTION
- * This function writes a DSP's System Parameters information.
- *
- * Note:
- * Or-together the desired bit-mask #defines that are listed below. Only
- * those algorithm parameters whose bit-mask is selected in the UpdateBits
- * function parameter will be updated.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-
-gpakWriteSysParmsStatus_t gpakWriteSystemParms(
- unsigned short int DspId, // DSP identifier
- GpakSystemParms_t *pSysParms, /* pointer to System Parms info var */
- unsigned short int UpdateBits, /* input: flags indicating which parms to update */
- GPAK_SysParmsStat_t *pStatus /* pointer to Write System Parms Status */
- )
-{
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
- DSP_WORD DspStatus; /* DSP's reply status */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (WspInvalidDsp);
-
- /* Build the Write System Parameters message. */
- MsgBuffer[0] = MSG_WRITE_SYS_PARMS << 8;
-
- if (UpdateBits & DTMF_UPDATE_MASK)
- {
- MsgBuffer[1] |= DTMF_UPDATE_MASK;
- MsgBuffer[8] = (DSP_WORD) pSysParms->MinSigLevel;
- MsgBuffer[9] = (DSP_WORD) (pSysParms->FreqDeviation & 0xff);
- if (pSysParms->SNRFlag)
- MsgBuffer[9] |= (1<<8);
- }
-
- MsgBuffer[10] = (DSP_WORD) 0;
- if (UpdateBits & DTMF_TWIST_UPDATE_MASK)
- {
- MsgBuffer[1] |= DTMF_TWIST_UPDATE_MASK;
- MsgBuffer[10] |= (DSP_WORD) (pSysParms->DtmfFwdTwist & 0x000f);
- MsgBuffer[10] |= (DSP_WORD) ((pSysParms->DtmfRevTwist << 4) & 0x00f0);
- }
-
-
- if (UpdateBits & DTMF_VALID_MASK)
- {
- MsgBuffer[1] |= DTMF_VALID_MASK;
- MsgBuffer[11] = (DSP_WORD) (pSysParms->DtmfValidityMask & 0x00ff);
- }
-
- /* Attempt to send the ping message to the DSP and receive it's
- reply. */
- if (!TransactCmd(DspId, MsgBuffer, 24, MSG_WRITE_SYS_PARMS_REPLY, 6, 0, 0))
- return (WspDspCommFailure);
-
- /* Return with an indication of success or failure based on the return
- status in the reply message. */
- *pStatus = (GPAK_SysParmsStat_t) (MsgBuffer[2] );
-
- DspStatus = (MsgBuffer[1] & 0xFF);
- if (DspStatus == 0)
- return (WspSuccess);
- else
- return (WspDspCommFailure);
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakReadSystemParms - Read a DSP's System Parameters.
- *
- * FUNCTION
- * This function reads a DSP's System Parameters information.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-gpakReadSysParmsStatus_t gpakReadSystemParms(
- unsigned short int DspId, // DSP identifier
- GpakSystemParms_t *pSysParms /* pointer to System Parms info var */
- )
-{
-
- DSP_WORD MsgBuffer[MSG_BUFFER_SIZE]; /* message buffer */
-
- /* Make sure the DSP Id is valid. */
- if (DspId >= MAX_DSP_CORES)
- return (RspInvalidDsp);
-
- /* Build the Read System Parameters message. */
- MsgBuffer[0] = MSG_READ_SYS_PARMS << 8;
-
- /* Attempt to send the ping message to the DSP and receive it's
- reply. */
- if (!TransactCmd(DspId, MsgBuffer, 2, MSG_READ_SYS_PARMS_REPLY, 22, 0, 0))
- return (RspDspCommFailure);
-
- /* Extract the System Parameters information from the message. */
- pSysParms->DtmfValidityMask = (short int)(MsgBuffer[7]) ;
-
- pSysParms->MinSigLevel = (short int)MsgBuffer[8];
- pSysParms->SNRFlag = (short int)((MsgBuffer[9]>>8) & 0x1);
- pSysParms->FreqDeviation = (short int)(MsgBuffer[9] & 0xff);
- pSysParms->DtmfFwdTwist = (short int)MsgBuffer[10] & 0x000f;
- pSysParms->DtmfRevTwist = (short int)(MsgBuffer[10] >> 4) & 0x000f;
-
- /* Return with an indication that System Parameters info was obtained. */
- return (RspSuccess);
-}
diff --git a/drivers/dahdi/wctdm24xxp/GpakCust.c b/drivers/dahdi/wctdm24xxp/GpakCust.c
deleted file mode 100644
index a32fb96..0000000
--- a/drivers/dahdi/wctdm24xxp/GpakCust.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (c) 2005, Adaptive Digital Technologies, Inc.
- *
- * File Name: GpakCust.c
- *
- * Description:
- * This file contains host system dependent functions to support generic
- * G.PAK API functions. The file is integrated into the host processor
- * connected to C55x G.PAK DSPs via a Host Port Interface.
- *
- * Note: This file needs to be modified by the G.PAK system integrator.
- *
- * Version: 1.0
- *
- * Revision History:
- * 06/15/05 - Initial release.
- *
- * This program has been released under the terms of the GPL version 2 by
- * permission of Adaptive Digital Technologies, Inc.
- *
- */
-
-/*
- * 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/version.h>
-#include <linux/delay.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-#include <linux/semaphore.h>
-#else
-#include <asm/semaphore.h>
-#endif
-
-#include <dahdi/kernel.h>
-
-#include "wctdm24xxp.h"
-#include "GpakCust.h"
-
-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;
- }
-}
-
-static inline struct wctdm * wc_find_iface(unsigned short dspid)
-{
- int i;
- struct wctdm *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 inline struct vpm150m_cmd * vpm150m_empty_slot(struct wctdm *wc)
-{
- int x;
-
- for (x = 0; x < VPM150M_MAX_COMMANDS; x++)
- if (!wc->vpm150m->cmdq[x].desc) {
- return &wc->vpm150m->cmdq[x];
- }
- return NULL;
-}
-
-/* Wait for any outstanding commands to be completed. */
-static inline int vpm150m_io_wait(struct wctdm *wc)
-{
- int x;
- int ret=0;
- for (x=0; x < VPM150M_MAX_COMMANDS;) {
- if (wc->vpm150m->cmdq[x].desc) {
- if ((ret=schluffen(&wc->regq))) {
- return ret;
- }
- x=0;
- }
- else {
- ++x;
- }
- }
- return ret;
-}
-
-static int wctdm_vpm150m_getreg_full_async(struct wctdm *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)->desc = __VPM150M_RD;
- if (pagechange) {
- (*hit_p)->desc |= __VPM150M_RWPAGE;
- }
- (*hit_p)->datalen = len;
- (*hit_p)->addr = addr;
- memset((*hit_p)->data, 0, len*sizeof(outbuf[0]));
- }
- else {
- ret = -EBUSY;
- }
- spin_unlock_irqrestore(&wc->reglock, flags);
- return ret;
-}
-
-static int wctdm_vpm150m_getreg_full_return(struct wctdm *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)->desc & __VPM150M_FIN) {
- memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0])));
- (*hit_p)->desc = 0;
- (*hit_p) = NULL;
- ret = 0;
- }
- else {
- spin_unlock_irqrestore(&wc->reglock, flags);
- if ((ret=schluffen(&wc->regq))) {
- return ret;
- }
- spin_lock_irqsave(&wc->reglock, flags);
- ret = -EBUSY;
- }
- } while (-EBUSY == ret);
- spin_unlock_irqrestore(&wc->reglock, flags);
- return ret;
-}
-
-static int wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
-{
- struct vpm150m_cmd *hit = NULL;
- int ret = 0;
- do {
- ret = wctdm_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit);
- if (!hit) {
- if ( -EBUSY == ret ) {
- if ((ret = schluffen(&wc->regq)))
- return ret;
- }
- BUG_ON(0 != ret);
- }
- } while (!hit);
- ret = wctdm_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit);
- return ret;
-}
-
-static int wctdm_vpm150m_setreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned int addr, unsigned short *data)
-{
- unsigned long flags;
- struct vpm150m_cmd *hit;
- int ret, i;
- do {
- spin_lock_irqsave(&wc->reglock, flags);
- hit = vpm150m_empty_slot(wc);
- if (hit) {
- hit->desc = __VPM150M_WR;
- if (pagechange)
- hit->desc |= __VPM150M_RWPAGE;
- hit->addr = addr;
- hit->datalen = len;
- for (i = 0; i < len; i++)
- hit->data[i] = data[i];
- }
- spin_unlock_irqrestore(&wc->reglock, flags);
- if (!hit) {
- if ((ret = schluffen(&wc->regq)))
- return ret;
- }
- } while (!hit);
- return (hit) ? 0 : -1;
-}
-
-int wctdm_vpm150m_setpage(struct wctdm *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 wctdm_vpm150m_setreg_full(wc, 1, 1, 0, &addr);
-}
-
-unsigned char wctdm_vpm150m_getpage(struct wctdm *wc)
-{
- unsigned short res;
- wctdm_vpm150m_getreg_full(wc, 1, 1, 0, &res);
- return res;
-}
-
-unsigned short wctdm_vpm150m_getreg(struct wctdm *wc, unsigned int len, unsigned int addr, unsigned short *data)
-{
- unsigned short res;
- wctdm_vpm150m_setpage(wc, addr >> 16);
- if ((addr >> 16) != ((addr + len) >> 16))
- printk(KERN_INFO "getreg: You found it!\n");
- res = wctdm_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
- return res;
-}
-
-int wctdm_vpm150m_setreg(struct wctdm *wc, unsigned int len, unsigned int addr, unsigned short *data)
-{
- int res;
- wctdm_vpm150m_setpage(wc, addr >> 16);
- if ((addr >> 16) != ((addr + len) >> 16))
- printk(KERN_INFO "getreg: You found it!\n");
- res = wctdm_vpm150m_setreg_full(wc, 0, len, addr & 0xffff, data);
- return res;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * 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 wctdm *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 };
- wctdm_vpm150m_setpage(wc, DspAddress >> 16);
- DspAddress &= 0xffff;
- for (i=0; i < NumWords; ++i) {
- ret = wctdm_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 = wctdm_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;
- wctdm_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 wctdm *wc = wc_find_iface(DspId);
- int i;
- int transcount;
-
- //printk(KERN_DEBUG "Writing %d words to memory\n", NumWords);
- if (wc && wc->vpm150m) {
- for (i = 0; i < NumWords;) {
- if ((NumWords - i) > VPM150M_MAX_DATA)
- transcount = VPM150M_MAX_DATA;
- else
- transcount = NumWords - i;
-
- wctdm_vpm150m_setreg(wc, transcount, DspAddress + i, &pWordValues[i]);
- i += transcount;
- }
-#if 0
- for (i = 0; i < NumWords; i++) {
- if (wctdm_vpm150m_getreg(wc, DspAddress + i) != pWordValues[i]) {
- printk(KERN_NOTICE "Error in write. Address %x is not %x\n", DspAddress + i, pWordValues[i]);
- }
- }
-#endif
- }
- 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 wctdm *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 wctdm *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 */
- )
-{
-#ifdef VPM150M_SUPPORT
- struct wctdm_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;
-#endif
-}
diff --git a/drivers/dahdi/wctdm24xxp/Kbuild b/drivers/dahdi/wctdm24xxp/Kbuild
index 69eddc3..6b1d0e7 100644
--- a/drivers/dahdi/wctdm24xxp/Kbuild
+++ b/drivers/dahdi/wctdm24xxp/Kbuild
@@ -1,18 +1,5 @@
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP) += wctdm24xxp.o
-FIRM_DIR := ../firmware
-
EXTRA_CFLAGS += -I$(src)/.. -Wno-undef
-ifeq ($(HOTPLUG_FIRMWARE),yes)
- EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
-endif
-
-wctdm24xxp-objs := base.o GpakCust.o GpakApi.o voicebus.o
-
-ifneq ($(HOTPLUG_FIRMWARE),yes)
-wctdm24xxp-objs += $(FIRM_DIR)/dahdi-fw-vpmadt032.o
-endif
-
-$(obj)/$(FIRM_DIR)/dahdi-fw-vpmadt032.o: $(obj)/base.o
- $(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-vpmadt032.o
+wctdm24xxp-objs := base.o
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index da48cfe..9a6a8ce 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -4,7 +4,7 @@
* Written by Mark Spencer <markster@digium.com>
* Support for TDM800P and VPM150M by Matthew Fredrickson <creslin@digium.com>
*
- * Copyright (C) 2005 - 2008 Digium, Inc.
+ * Copyright (C) 2005 - 2009 Digium, Inc.
* All rights reserved.
*
* Sections for QRV cards written by Jim Dixon <jim@lambdatel.com>
@@ -58,12 +58,10 @@ Tx Gain - W/Pre-Emphasis: -23.99 to 0.00 db
#include "wctdm24xxp.h"
-#ifdef VPM150M_SUPPORT
#include "adt_lec.h"
-#endif
-#include "GpakCust.h"
-#include "GpakApi.h"
+#include "voicebus/GpakCust.h"
+#include "voicebus/GpakApi.h"
/*
Experimental max loop current limit for the proslic
@@ -213,11 +211,8 @@ static int neonmwi_envelope = 10;
static int neonmwi_offlimit = 16000; /* Time in milliseconds the monitor is checked before saying no message is waiting */
static int neonmwi_offlimit_cycles; /* Time in milliseconds the monitor is checked before saying no message is waiting */
-#ifdef VPM_SUPPORT
static int vpmsupport = 1;
-static int vpmdtmfsupport = 0;
-#define VPM_DEFAULT_DTMFTHRESHOLD 1250
-static int dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
+
/*
* This parameter is used to adjust the NLP type used. The options are:
* 0 : None
@@ -232,7 +227,6 @@ static int vpmnlptype = 1;
static int vpmnlpthresh = 24;
/* See vpmnlptype = 4 for more info */
static int vpmnlpmaxsupp = 0;
-#endif
static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane);
@@ -276,12 +270,193 @@ static inline int empty_slot(struct wctdm *wc, int card)
return -1;
}
-#ifdef VPM_SUPPORT
-static inline void cmd_dequeue_vpm150m(struct wctdm *wc, volatile unsigned char *writechunk, int whichframe)
+void setchanconfig_from_state(struct vpmadt032 *vpm, int channel, GpakChannelConfig_t *chanconfig)
+{
+ const struct vpmadt032_options *options;
+
+ BUG_ON(!vpm);
+
+ options = &vpm->options;
+
+ chanconfig->PcmInPortA = 3;
+ chanconfig->PcmInSlotA = channel;
+ chanconfig->PcmOutPortA = SerialPortNull;
+ chanconfig->PcmOutSlotA = channel;
+ chanconfig->PcmInPortB = 2;
+ chanconfig->PcmInSlotB = channel;
+ chanconfig->PcmOutPortB = 3;
+ chanconfig->PcmOutSlotB = channel;
+ 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;
+
+ switch (vpm->span->deflaw) {
+ case DAHDI_LAW_MULAW:
+ chanconfig->SoftwareCompand = cmpPCMU;
+ break;
+ case DAHDI_LAW_ALAW:
+ chanconfig->SoftwareCompand = cmpPCMA;
+ break;
+ default:
+ chanconfig->SoftwareCompand = cmpPCMU;
+ break;
+ }
+
+ chanconfig->FrameRate = rate2ms;
+ chanconfig->EcanParametersA.EcanTapLength = 1024;
+ chanconfig->EcanParametersA.EcanNlpType = vpm->curecstate[channel].nlp_type;
+ chanconfig->EcanParametersA.EcanAdaptEnable = 1;
+ chanconfig->EcanParametersA.EcanG165DetEnable = 1;
+ chanconfig->EcanParametersA.EcanDblTalkThresh = 6;
+ chanconfig->EcanParametersA.EcanNlpThreshold = vpm->curecstate[channel].nlp_threshold;
+ chanconfig->EcanParametersA.EcanNlpConv = 0;
+ chanconfig->EcanParametersA.EcanNlpUnConv = 0;
+ chanconfig->EcanParametersA.EcanNlpMaxSuppress = vpm->curecstate[channel].nlp_max_suppress;
+ chanconfig->EcanParametersA.EcanCngThreshold = 43;
+ chanconfig->EcanParametersA.EcanAdaptLimit = 50;
+ chanconfig->EcanParametersA.EcanCrossCorrLimit = 15;
+ chanconfig->EcanParametersA.EcanNumFirSegments = 3;
+ chanconfig->EcanParametersA.EcanFirSegmentLen = 48;
+
+ memcpy(&chanconfig->EcanParametersB,
+ &chanconfig->EcanParametersA,
+ sizeof(chanconfig->EcanParametersB));
+}
+
+static int config_vpmadt032(struct vpmadt032 *vpm)
+{
+ int res, i;
+ GpakPortConfig_t portconfig = {0};
+ gpakConfigPortStatus_t configportstatus;
+ GPAK_PortConfigStat_t pstatus;
+ GpakChannelConfig_t chanconfig;
+ GPAK_ChannelConfigStat_t cstatus;
+ GPAK_AlgControlStat_t algstatus;
+
+ /* 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 = SlotCfg2Groups;
+ portconfig.FirstBlockNum2 = 0;
+ portconfig.FirstSlotMask2 = 0xffff;
+ portconfig.SecBlockNum2 = 1;
+ portconfig.SecSlotMask2 = 0xffff;
+ portconfig.SerialWordSize2 = SerWordSize8;
+ portconfig.CompandingMode2 = cmpNone;
+ portconfig.TxFrameSyncPolarity2 = FrameSyncActHigh;
+ portconfig.RxFrameSyncPolarity2 = FrameSyncActHigh;
+ portconfig.TxClockPolarity2 = SerClockActHigh;
+ portconfig.RxClockPolarity2 = SerClockActLow;
+ portconfig.TxDataDelay2 = DataDelay0;
+ portconfig.RxDataDelay2 = DataDelay0;
+ portconfig.DxDelay2 = Disabled;
+ portconfig.ThirdSlotMask2 = 0x0000;
+ portconfig.FouthSlotMask2 = 0x0000;
+ portconfig.FifthSlotMask2 = 0x0000;
+ portconfig.SixthSlotMask2 = 0x0000;
+ portconfig.SevenSlotMask2 = 0x0000;
+ portconfig.EightSlotMask2 = 0x0000;
+
+ /* Third Serial Port Config */
+ portconfig.SlotsSelect3 = SlotCfg2Groups;
+ portconfig.FirstBlockNum3 = 0;
+ portconfig.FirstSlotMask3 = 0xffff;
+ portconfig.SecBlockNum3 = 1;
+ portconfig.SecSlotMask3 = 0xffff;
+ 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 = 0x0000;
+ portconfig.FouthSlotMask3 = 0x0000;
+ portconfig.FifthSlotMask3 = 0x0000;
+ portconfig.SixthSlotMask3 = 0x0000;
+ portconfig.SevenSlotMask3 = 0x0000;
+ portconfig.EightSlotMask3 = 0x0000;
+
+ if ((configportstatus = gpakConfigurePorts(vpm->dspid, &portconfig, &pstatus))) {
+ printk(KERN_NOTICE "Configuration of ports failed (%d)!\n", configportstatus);
+ return -1;
+ } else {
+ if (vpm->options.debug & DEBUG_ECHOCAN)
+ printk(KERN_DEBUG "Configured McBSP ports successfully\n");
+ }
+
+ if ((res = gpakPingDsp(vpm->dspid, &vpm->version))) {
+ printk(KERN_NOTICE "Error pinging DSP (%d)\n", res);
+ return -1;
+ }
+
+ for (i = 0; i < vpm->span->channels; ++i) {
+ vpm->curecstate[i].tap_length = 0;
+ vpm->curecstate[i].nlp_type = vpm->options.vpmnlptype;
+ vpm->curecstate[i].nlp_threshold = vpm->options.vpmnlpthresh;
+ vpm->curecstate[i].nlp_max_suppress = vpm->options.vpmnlpmaxsupp;
+ memcpy(&vpm->desiredecstate[i], &vpm->curecstate[i], sizeof(vpm->curecstate[i]));
+
+ /* set_vpmadt032_chanconfig_from_state(&vpm->curecstate[i], &vpm->options, i, &chanconfig); !!! */
+ vpm->setchanconfig_from_state(vpm, i, &chanconfig);
+ if ((res = gpakConfigureChannel(vpm->dspid, i, tdmToTdm, &chanconfig, &cstatus))) {
+ printk(KERN_NOTICE "Unable to configure channel #%d (%d)", i, res);
+ if (res == 1) {
+ printk(", reason %d", cstatus);
+ }
+ printk("\n");
+ return -1;
+ }
+
+ if ((res = gpakAlgControl(vpm->dspid, i, BypassEcanA, &algstatus))) {
+ printk(KERN_NOTICE "Unable to disable echo can on channel %d (reason %d:%d)\n", i + 1, res, algstatus);
+ return -1;
+ }
+ }
+
+ if ((res = gpakPingDsp(vpm->dspid, &vpm->version))) {
+ printk(KERN_NOTICE "Error pinging DSP (%d)\n", res);
+ return -1;
+ }
+
+ set_bit(VPM150M_ACTIVE, &vpm->control);
+
+ return 0;
+}
+
+
+static inline void cmd_dequeue_vpmadt032(struct wctdm *wc, unsigned char *writechunk, int whichframe)
{
unsigned long flags;
- struct vpm150m_cmd *curcmd = NULL;
- struct vpm150m *vpm150m = wc->vpm150m;
+ struct vpmadt032_cmd *curcmd = NULL;
+ struct vpmadt032 *vpmadt032 = wc->vpmadt032;
int x;
unsigned char leds = ~((wc->intcount / 1000) % 8) & 0x7;
@@ -290,14 +465,14 @@ static inline void cmd_dequeue_vpm150m(struct wctdm *wc, volatile unsigned char
spin_lock_irqsave(&wc->reglock, flags);
- if (test_bit(VPM150M_SPIRESET, &vpm150m->control) || test_bit(VPM150M_HPIRESET, &vpm150m->control)) {
+ if (test_bit(VPM150M_SPIRESET, &vpmadt032->control) || test_bit(VPM150M_HPIRESET, &vpmadt032->control)) {
if (debug & DEBUG_ECHOCAN)
printk(KERN_INFO "HW Resetting VPMADT032...\n");
for (x = 24; x < 28; x++) {
if (x == 24) {
- if (test_and_clear_bit(VPM150M_SPIRESET, &vpm150m->control))
+ if (test_and_clear_bit(VPM150M_SPIRESET, &vpmadt032->control))
writechunk[CMD_BYTE(x, 0, 0)] = 0x08;
- else if (test_and_clear_bit(VPM150M_HPIRESET, &vpm150m->control))
+ else if (test_and_clear_bit(VPM150M_HPIRESET, &vpmadt032->control))
writechunk[CMD_BYTE(x, 0, 0)] = 0x0b;
} else
writechunk[CMD_BYTE(x, 0, 0)] = 0x00 | leds;
@@ -308,20 +483,11 @@ static inline void cmd_dequeue_vpm150m(struct wctdm *wc, volatile unsigned char
return;
}
-
- /* Search for something waiting to transmit */
- for (x = 0; x < VPM150M_MAX_COMMANDS; x++) {
- if ((vpm150m->cmdq[x].desc & (__VPM150M_RD | __VPM150M_WR)) &&
- !(vpm150m->cmdq[x].desc & (__VPM150M_FIN | __VPM150M_TX))) {
- curcmd = &vpm150m->cmdq[x];
- curcmd->txident = wc->txident;
- curcmd->desc |= __VPM150M_TX;
- break;
- }
- }
- if (curcmd) {
+ if ((curcmd = vpmadt032_get_ready_cmd(vpmadt032))) {
+ curcmd->txident = wc->txident;
#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);
+ // if (printk_ratelimit())
+ printk(KERN_DEBUG "Transmitting txident = %d, desc = 0x%x, addr = 0x%x, data = 0x%x\n", curcmd->txident, curcmd->desc, curcmd->address, curcmd->data);
#endif
if (curcmd->desc & __VPM150M_RWPAGE) {
/* Set CTRL access to page*/
@@ -336,7 +502,7 @@ static inline void cmd_dequeue_vpm150m(struct wctdm *wc, volatile unsigned char
writechunk[CMD_BYTE(25, 0, 0)] = ((0x8 | 0x4 | 0x1) << 4);
writechunk[CMD_BYTE(25, 1, 0)] = 0;
if (curcmd->desc & __VPM150M_WR)
- writechunk[CMD_BYTE(25, 2, 0)] = curcmd->data[0] & 0xf;
+ writechunk[CMD_BYTE(25, 2, 0)] = curcmd->data & 0xf;
else
writechunk[CMD_BYTE(25, 2, 0)] = 0;
@@ -353,54 +519,25 @@ static inline void cmd_dequeue_vpm150m(struct wctdm *wc, volatile unsigned char
} else {
/* Set address */
writechunk[CMD_BYTE(24, 0, 0)] = ((0x8 | 0x4) << 4);
- writechunk[CMD_BYTE(24, 1, 0)] = (curcmd->addr >> 8) & 0xff;
- writechunk[CMD_BYTE(24, 2, 0)] = curcmd->addr & 0xff;
+ writechunk[CMD_BYTE(24, 1, 0)] = (curcmd->address >> 8) & 0xff;
+ writechunk[CMD_BYTE(24, 2, 0)] = curcmd->address & 0xff;
/* Send/Get our data */
- if (curcmd->desc & __VPM150M_WR) {
- if (curcmd->datalen > 1)
- writechunk[CMD_BYTE(25, 0, 0)] = ((0x8 | (0x1 << 1)) << 4);
- else
- writechunk[CMD_BYTE(25, 0, 0)] = ((0x8 | (0x3 << 1)) << 4);
- } else
- if (curcmd->datalen > 1)
- writechunk[CMD_BYTE(25, 0, 0)] = ((0x8 | (0x1 << 1) | 0x1) << 4);
- else
- writechunk[CMD_BYTE(25, 0, 0)] = ((0x8 | (0x3 << 1) | 0x1) << 4);
- writechunk[CMD_BYTE(25, 1, 0)] = (curcmd->data[0] >> 8) & 0xff;
- writechunk[CMD_BYTE(25, 2, 0)] = curcmd->data[0] & 0xff;
+ writechunk[CMD_BYTE(25, 0, 0)] = (curcmd->desc & __VPM150M_WR) ?
+ ((0x8 | (0x3 << 1)) << 4) : ((0x8 | (0x3 << 1) | 0x1) << 4);
+ writechunk[CMD_BYTE(25, 1, 0)] = (curcmd->data >> 8) & 0xff;
+ writechunk[CMD_BYTE(25, 2, 0)] = curcmd->data & 0xff;
- if (curcmd->datalen > 1) {
- if (curcmd->desc & __VPM150M_WR)
- writechunk[CMD_BYTE(26, 0, 0)] = ((0x8 | (0x1 << 1)) << 4);
- else
- writechunk[CMD_BYTE(26, 0, 0)] = ((0x8 | (0x1 << 1) | 0x1) << 4);
- writechunk[CMD_BYTE(26, 1, 0)] = (curcmd->data[1] >> 8) & 0xff;
- writechunk[CMD_BYTE(26, 2, 0)] = curcmd->data[1] & 0xff;
- } else {
- /* Fill in the rest */
- writechunk[CMD_BYTE(26, 0, 0)] = 0;
- writechunk[CMD_BYTE(26, 1, 0)] = 0;
- writechunk[CMD_BYTE(26, 2, 0)] = 0;
- }
-
- if (curcmd->datalen > 2) {
- if (curcmd->desc & __VPM150M_WR)
- writechunk[CMD_BYTE(27, 0, 0)] = ((0x8 | (0x1 << 1)) << 4);
- else
- writechunk[CMD_BYTE(27, 0, 0)] = ((0x8 | (0x1 << 1) | 0x1) << 4);
- writechunk[CMD_BYTE(27, 1, 0)] = (curcmd->data[2] >> 8) & 0xff;
- writechunk[CMD_BYTE(27, 2, 0)] = curcmd->data[2] & 0xff;
- } else {
- /* Fill in the rest */
- writechunk[CMD_BYTE(27, 0, 0)] = 0;
- writechunk[CMD_BYTE(27, 1, 0)] = 0;
- writechunk[CMD_BYTE(27, 2, 0)] = 0;
- }
-
+ writechunk[CMD_BYTE(26, 0, 0)] = 0;
+ writechunk[CMD_BYTE(26, 1, 0)] = 0;
+ writechunk[CMD_BYTE(26, 2, 0)] = 0;
+ /* Fill in the rest */
+ writechunk[CMD_BYTE(27, 0, 0)] = 0;
+ writechunk[CMD_BYTE(27, 1, 0)] = 0;
+ writechunk[CMD_BYTE(27, 2, 0)] = 0;
}
- } else if (test_and_clear_bit(VPM150M_SWRESET, &vpm150m->control)) {
+ } else if (test_and_clear_bit(VPM150M_SWRESET, &vpmadt032->control)) {
printk(KERN_INFO "Booting VPMADT032\n");
for (x = 24; x < 28; x++) {
if (x == 24)
@@ -421,19 +558,18 @@ static inline void cmd_dequeue_vpm150m(struct wctdm *wc, volatile unsigned char
}
}
-#ifdef VPM150M_SUPPORT
/* Add our leds in */
- for (x = 24; x < 28; x++)
+ for (x = 24; x < 28; x++) {
writechunk[CMD_BYTE(x, 0, 0)] |= leds;
+ }
/* Now let's figure out if we need to check for DTMF */
- if (test_bit(VPM150M_ACTIVE, &vpm150m->control) && !whichframe && !(wc->intcount % 100))
- queue_work(vpm150m->wq, &vpm150m->work);
-#endif
+ if (test_bit(VPM150M_ACTIVE, &vpmadt032->control) && !whichframe && !(wc->intcount % 100)) {
+ schedule_work(&vpmadt032->work);
+ }
spin_unlock_irqrestore(&wc->reglock, flags);
}
-#endif /* VPM_SUPPORT */
static inline void cmd_dequeue(struct wctdm *wc, volatile unsigned char *writechunk, int card, int pos)
{
@@ -519,7 +655,6 @@ static inline void cmd_dequeue(struct wctdm *wc, volatile unsigned char *writech
writechunk[CMD_BYTE(card, 2, wc->altcs[card])] = 0x80;
else
writechunk[CMD_BYTE(card, 2, wc->altcs[card])] = 0x00;
-#ifdef VPM_SUPPORT
} else if (wc->modtype[card] == MOD_TYPE_VPM) {
if (curcmd & __CMD_WR)
writechunk[CMD_BYTE(card, 0, wc->altcs[card])] = ((card & 0x3) << 4) | 0xc | ((curcmd >> 16) & 0x1);
@@ -528,7 +663,7 @@ static inline void cmd_dequeue(struct wctdm *wc, volatile unsigned char *writech
writechunk[CMD_BYTE(card, 1, wc->altcs[card])] = (curcmd >> 8) & 0xff;
writechunk[CMD_BYTE(card, 2, wc->altcs[card])] = curcmd & 0xff;
} else if (wc->modtype[card] == MOD_TYPE_VPM150M) {
-#endif
+ ;
} else if (wc->modtype[card] == MOD_TYPE_QRV) {
writechunk[CMD_BYTE(card, 0, wc->altcs[card])] = 0x00;
@@ -562,42 +697,52 @@ static inline void cmd_dequeue(struct wctdm *wc, volatile unsigned char *writech
#endif
}
-#ifdef VPM_SUPPORT
-static inline void cmd_decifer_vpm150m(struct wctdm *wc, volatile unsigned char *readchunk)
+static inline void cmd_decipher_vpmadt032(struct wctdm *wc, unsigned char *readchunk)
{
unsigned long flags;
- unsigned char ident;
- int x, i;
+ struct vpmadt032 *vpm = wc->vpmadt032;
+ struct vpmadt032_cmd *cmd;
+
+ BUG_ON(!vpm);
+
+ /* If the hardware is not processing any commands currently, then
+ * there is nothing for us to do here. */
+ if (list_empty(&vpm->active_cmds)) {
+ return;
+ }
+
+ spin_lock_irqsave(&vpm->list_lock, flags);
+ cmd = list_entry(vpm->active_cmds.next, struct vpmadt032_cmd, node);
+ if (wc->rxident == cmd->txident) {
+ list_del_init(&cmd->node);
+ } else {
+ cmd = NULL;
+ }
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+
+ if (!cmd) {
+ return;
+ }
/* Skip audio */
readchunk += 24;
- spin_lock_irqsave(&wc->reglock, flags);
- /* Search for any pending results */
- for (x = 0; x < VPM150M_MAX_COMMANDS; x++) {
- if ((wc->vpm150m->cmdq[x].desc & (__VPM150M_RD | __VPM150M_WR)) &&
- (wc->vpm150m->cmdq[x].desc & (__VPM150M_TX)) &&
- !(wc->vpm150m->cmdq[x].desc & (__VPM150M_FIN))) {
- ident = wc->vpm150m->cmdq[x].txident;
- 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((25 + i), 1, 0)]) << 8;
- wc->vpm150m->cmdq[x].data[i] |= readchunk[CMD_BYTE((25 + i), 2, 0)];
- }
- if (wc->vpm150m->cmdq[x].desc & __VPM150M_WR) {
- /* Go ahead and clear out writes since they need no acknowledgement */
- wc->vpm150m->cmdq[x].desc = 0;
- } else
- wc->vpm150m->cmdq[x].desc |= __VPM150M_FIN;
- break;
- }
- }
+ /* Store result */
+ cmd->data = (0xff & readchunk[CMD_BYTE(25, 1, 0)]) << 8;
+ cmd->data |= readchunk[CMD_BYTE(25, 2, 0)];
+ if (cmd->desc & __VPM150M_WR) {
+ /* Writes do not need any acknowledgement */
+ list_add_tail(&cmd->node, &vpm->free_cmds);
+ } else {
+ cmd->desc |= __VPM150M_FIN;
+ complete(&cmd->complete);
}
- spin_unlock_irqrestore(&wc->reglock, flags);
+#if 0
+ // if (printk_ratelimit())
+ printk(KERN_DEBUG "Received txident = %d, desc = 0x%x, addr = 0x%x, data = 0x%x\n", cmd->txident, cmd->desc, cmd->address, cmd->data);
+#endif
}
-#endif /* VPM_SUPPORT */
-static inline void cmd_decifer(struct wctdm *wc, volatile unsigned char *readchunk, int card)
+static inline void cmd_decipher(struct wctdm *wc, volatile unsigned char *readchunk, int card)
{
unsigned long flags;
unsigned char ident;
@@ -700,10 +845,9 @@ static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char *writechun
}
cmd_dequeue(wc, writechunk, y, x);
}
-#ifdef VPM_SUPPORT
if (!x)
wc->blinktimer++;
- if (wc->vpm) {
+ if (wc->vpm100) {
for (y=24;y<28;y++) {
if (!x) {
cmd_checkisr(wc, y);
@@ -711,19 +855,19 @@ static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char *writechun
cmd_dequeue(wc, writechunk, y, x);
}
#ifdef FANCY_ECHOCAN
- if (wc->vpm && wc->blinktimer >= 0xf) {
+ if (wc->vpm100 && wc->blinktimer >= 0xf) {
wc->blinktimer = -1;
wc->echocanpos++;
}
#endif
- } else if (wc->vpm150m) {
- cmd_dequeue_vpm150m(wc, writechunk, x);
+ } else if (wc->vpmadt032) {
+ cmd_dequeue_vpmadt032(wc, writechunk, x);
}
-#endif
+
if (x < DAHDI_CHUNKSIZE - 1) {
writechunk[EFRAME_SIZE] = wc->ctlreg;
writechunk[EFRAME_SIZE + 1] = wc->txident++;
-#if 1
+
if ((wc->type == 4) && ((wc->ctlreg & 0x10) || (wc->modtype[NUM_CARDS] == MOD_TYPE_NONE))) {
writechunk[EFRAME_SIZE + 2] = 0;
for (y = 0; y < 4; y++) {
@@ -732,7 +876,6 @@ static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char *writechun
}
} else
writechunk[EFRAME_SIZE + 2] = 0xf;
-#endif
}
writechunk += (EFRAME_SIZE + EFRAME_GAP);
}
@@ -814,7 +957,6 @@ static inline int wctdm_getreg(struct wctdm *wc, int card, int addr)
return ret;
}
-#ifdef VPM_SUPPORT
static inline unsigned char wctdm_vpm_in(struct wctdm *wc, int unit, const unsigned int addr)
{
return wctdm_getreg(wc, unit + NUM_CARDS, addr);
@@ -825,22 +967,24 @@ static inline void wctdm_vpm_out(struct wctdm *wc, int unit, const unsigned int
wctdm_setreg(wc, unit + NUM_CARDS, addr, val);
}
-static inline void cmd_vpm150m_retransmit(struct wctdm *wc)
+/* TODO: this should go in the dahdi_voicebus module... */
+static inline void cmd_vpmadt032_retransmit(struct wctdm *wc)
{
unsigned long flags;
- int x;
+ struct vpmadt032 *vpmadt032 = wc->vpmadt032;
+ struct vpmadt032_cmd *cmd, *temp;
- spin_lock_irqsave(&wc->reglock, flags);
- for (x = 0; x < VPM150M_MAX_COMMANDS; x++) {
- if (!(wc->vpm150m->cmdq[x].desc & __VPM150M_FIN)) {
- //printk(KERN_DEBUG "Retransmit!\n");
- wc->vpm150m->cmdq[x].desc &= ~(__VPM150M_TX);
- }
- }
- spin_unlock_irqrestore(&wc->reglock, flags);
+ BUG_ON(!vpmadt032);
+ /* By moving the commands back to the pending list, they will be
+ * transmitted when room is available */
+ spin_lock_irqsave(&vpmadt032->list_lock, flags);
+ list_for_each_entry_safe(cmd, temp, &vpmadt032->active_cmds, node) {
+ cmd->desc &= ~(__VPM150M_TX);
+ list_move_tail(&cmd->node, &vpmadt032->pending_cmds);
+ }
+ spin_unlock_irqrestore(&vpmadt032->list_lock, flags);
}
-#endif
static inline void cmd_retransmit(struct wctdm *wc)
{
@@ -856,8 +1000,8 @@ static inline void cmd_retransmit(struct wctdm *wc)
}
spin_unlock_irqrestore(&wc->reglock, flags);
#ifdef VPM_SUPPORT
- if (wc->vpm150m)
- cmd_vpm150m_retransmit(wc);
+ if (wc->vpmadt032)
+ cmd_vpmadt032_retransmit(wc);
#endif
}
@@ -883,15 +1027,14 @@ static inline void wctdm_receiveprep(struct wctdm *wc, unsigned char *readchunk)
wc->chans[y]->readchunk[x] = readchunk[y];
}
}
- cmd_decifer(wc, readchunk, y);
+ cmd_decipher(wc, readchunk, y);
}
-#ifdef VPM_SUPPORT
- if (wc->vpm) {
+ if (wc->vpm100) {
for (y=NUM_CARDS;y < NUM_CARDS + NUM_EC; y++)
- cmd_decifer(wc, readchunk, y);
- } else if (wc->vpm150m)
- cmd_decifer_vpm150m(wc, readchunk);
-#endif
+ cmd_decipher(wc, readchunk, y);
+ } else if (wc->vpmadt032) {
+ cmd_decipher_vpmadt032(wc, readchunk);
+ }
readchunk += (EFRAME_SIZE + EFRAME_GAP);
}
@@ -1466,7 +1609,6 @@ static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
}
-#ifdef VPM_SUPPORT
static inline void wctdm_vpm_check(struct wctdm *wc, int x)
{
if (wc->cmdq[x].isrshadow[0]) {
@@ -1486,19 +1628,18 @@ static inline void wctdm_vpm_check(struct wctdm *wc, int x)
}
}
-#include "adt_lec.c"
-
-static int wctdm_echocan_with_params(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
+static int wctdm_echocan_with_params(struct dahdi_chan *chan,
+ struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
{
struct wctdm *wc = chan->pvt;
- if (wc->vpm) {
+ if (wc->vpm100) {
int channel;
int unit;
channel = (chan->chanpos - 1);
unit = (chan->chanpos - 1) & 0x3;
- if (wc->vpm < 2)
+ if (wc->vpm100 < 2)
channel >>= 2;
if(debug & DEBUG_ECHOCAN)
@@ -1510,27 +1651,13 @@ static int wctdm_echocan_with_params(struct dahdi_chan *chan, struct dahdi_echoc
wctdm_vpm_out(wc,unit,channel,0x01);
return 0;
-#ifdef VPM150M_SUPPORT
- } else if (wc->vpm150m) {
- struct vpm150m *vpm150m = wc->vpm150m;
- unsigned int ret;
- int channo = chan->chanpos - 1;
-
- if ((ret = adt_lec_parse_params(&vpm150m->desiredecstate[channo], ecp, p)))
- return ret;
-
- vpm150m->desiredecstate[channo].tap_length = ecp->tap_length;
-
- if (memcmp(&vpm150m->curecstate[channo], &vpm150m->desiredecstate[channo], sizeof(vpm150m->curecstate[channo]))
- && test_bit(VPM150M_ACTIVE, &vpm150m->control))
- queue_work(vpm150m->wq, &vpm150m->work);
-
- return 0;
-#endif
- } else
+ } else if (wc->vpmadt032) {
+ return vpmadt032_echocan_with_params(wc->vpmadt032,
+ chan->chanpos-1, ecp, p);
+ } else {
return -ENODEV;
+ }
}
-#endif
static inline void wctdm_isr_misc(struct wctdm *wc)
{
@@ -1581,13 +1708,11 @@ static inline void wctdm_isr_misc(struct wctdm *wc)
}
}
}
-#ifdef VPM_SUPPORT
- if (wc->vpm > 0) {
+ if (wc->vpm100 > 0) {
for (x=NUM_CARDS;x<NUM_CARDS+NUM_EC;x++) {
wctdm_vpm_check(wc, x);
}
}
-#endif
}
static void handle_receive(void* vbb, void* context)
@@ -2598,27 +2723,8 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
break;
#ifdef VPM_SUPPORT
case DAHDI_TONEDETECT:
- if (get_user(x, (__user int *) data))
- return -EFAULT;
- if (!wc->vpm && !wc->vpm150m)
- return -ENOSYS;
- if ((wc->vpm || wc->vpm150m) && (x && !vpmdtmfsupport))
- return -ENOSYS;
- if (x & DAHDI_TONEDETECT_ON) {
- set_bit(chan->chanpos - 1, &wc->dtmfmask);
- } else {
- clear_bit(chan->chanpos - 1, &wc->dtmfmask);
- }
- if (x & DAHDI_TONEDETECT_MUTE) {
- if (wc->vpm150m) {
- set_bit(chan->chanpos - 1, &wc->vpm150m->desireddtmfmutestate);
- }
- } else {
- if (wc->vpm150m) {
- clear_bit(chan->chanpos - 1, &wc->vpm150m->desireddtmfmutestate);
- }
- }
- return 0;
+ /* Hardware DTMF detection is not supported. */
+ return -ENOSYS;
#endif
case DAHDI_SETPOLARITY:
if (get_user(x, (__user int *) data))
@@ -3107,589 +3213,14 @@ static void wctdm_post_initialize(struct wctdm *wc)
}
}
- if (wc->vpm)
+ if (wc->vpm100) {
strncat(wc->span.devicetype, " with VPM100M", sizeof(wc->span.devicetype) - 1);
- else if (wc->vpm150m)
+ } else if (wc->vpmadt032) {
strncat(wc->span.devicetype, " with VPMADT032", sizeof(wc->span.devicetype) - 1);
-}
-
-#ifdef VPM_SUPPORT
-
-#ifdef VPM150M_SUPPORT
-
-static void vpm150m_set_chanconfig_from_state(struct adt_lec_params * parms, int channum, GpakChannelConfig_t *chanconfig)
-{
- chanconfig->PcmInPortA = 3;
- chanconfig->PcmInSlotA = channum;
- chanconfig->PcmOutPortA = SerialPortNull;
- chanconfig->PcmOutSlotA = channum;
- chanconfig->PcmInPortB = 2;
- chanconfig->PcmInSlotB = channum;
- chanconfig->PcmOutPortB = 3;
- chanconfig->PcmOutSlotB = channum;
- 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;
-
- if (alawoverride)
- chanconfig->SoftwareCompand = cmpPCMA;
- else
- chanconfig->SoftwareCompand = cmpPCMU;
-
- chanconfig->FrameRate = rate2ms;
- chanconfig->EcanParametersA.EcanTapLength = 1024;
- chanconfig->EcanParametersA.EcanNlpType = parms->nlp_type;
- chanconfig->EcanParametersA.EcanAdaptEnable = 1;
- chanconfig->EcanParametersA.EcanG165DetEnable = 1;
- chanconfig->EcanParametersA.EcanDblTalkThresh = 6;
- chanconfig->EcanParametersA.EcanNlpThreshold = parms->nlp_threshold;
- chanconfig->EcanParametersA.EcanNlpConv = 0;
- chanconfig->EcanParametersA.EcanNlpUnConv = 0;
- chanconfig->EcanParametersA.EcanNlpMaxSuppress = parms->nlp_max_suppress;
- 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 = parms->nlp_type;
- chanconfig->EcanParametersB.EcanAdaptEnable = 1;
- chanconfig->EcanParametersB.EcanG165DetEnable = 1;
- chanconfig->EcanParametersB.EcanDblTalkThresh = 6;
- chanconfig->EcanParametersB.EcanNlpThreshold = parms->nlp_threshold;
- chanconfig->EcanParametersB.EcanNlpConv = 0;
- chanconfig->EcanParametersB.EcanNlpUnConv = 0;
- chanconfig->EcanParametersB.EcanNlpMaxSuppress = parms->nlp_max_suppress;
- chanconfig->EcanParametersB.EcanCngThreshold = 43;
- chanconfig->EcanParametersB.EcanAdaptLimit = 50;
- chanconfig->EcanParametersB.EcanCrossCorrLimit = 15;
- chanconfig->EcanParametersB.EcanNumFirSegments = 3;
- chanconfig->EcanParametersB.EcanFirSegmentLen = 64;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void vpm150m_bh(void *data)
-{
- struct vpm150m *vpm150m = data;
-#else
-static void vpm150m_bh(struct work_struct *data)
-{
- struct vpm150m *vpm150m = container_of(data, struct vpm150m, work);
-#endif
- struct wctdm *wc = vpm150m->wc;
- int i;
-
- for (i = 0; i < wc->type; 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 = wc->intcount;
- GPAK_AlgControlStat_t pstatus;
- int res;
-
- if (enable) {
- res = gpakAlgControl(vpm150m->dspid, i, EnableDTMFMuteA, &pstatus);
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "DTMF mute enable took %d ms\n", wc->intcount - start);
- } else {
- res = gpakAlgControl(vpm150m->dspid, i, DisableDTMFMuteA, &pstatus);
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "DTMF mute disable took %d ms\n", wc->intcount - 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 = wc->intcount;
-
- do {
- res = gpakReadEventFIFOMessage(vpm150m->dspid, &channel, &eventcode, &eventdata);
-
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "ReadEventFIFOMessage took %d ms\n", wc->intcount - start);
-
- if (res == RefInvalidEvent || res == RefDspCommFailure) {
- printk(KERN_NOTICE "VPM Comm Error\n");
- continue;
- }
-
- if (res == RefNoEventAvail) {
- continue;
- }
-
- if (eventcode == EventToneDetect) {
- GpakToneCodes_t tone = eventdata.toneEvent.ToneCode;
- int duration = eventdata.toneEvent.ToneDuration;
- char zaptone = vpm150mtone_to_zaptone(tone);
-
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "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];
-
- 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)) {
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "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)) {
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "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 != RefNoEventAvail) && (res != RefInvalidEvent) && (res != RefDspCommFailure));
- }
-
- for (i = 0; i < wc->type; i++) {
- unsigned int start = wc->intcount;
- GPAK_AlgControlStat_t pstatus;
- int res = 1;
-
- if ((vpm150m->desiredecstate[i].nlp_type != vpm150m->curecstate[i].nlp_type)
- || (vpm150m->desiredecstate[i].nlp_threshold != vpm150m->curecstate[i].nlp_threshold)
- || (vpm150m->desiredecstate[i].nlp_max_suppress != vpm150m->curecstate[i].nlp_max_suppress)) {
-
- GPAK_ChannelConfigStat_t cstatus;
- GPAK_TearDownChanStat_t tstatus;
- GpakChannelConfig_t chanconfig;
-
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "Reconfiguring chan %d for nlp %d, nlp_thresh %d, and max_supp %d\n", i + 1, vpm150m->desiredecstate[i].nlp_type,
- vpm150m->desiredecstate[i].nlp_threshold, vpm150m->desiredecstate[i].nlp_max_suppress);
-
- vpm150m_set_chanconfig_from_state(&vpm150m->desiredecstate[i], i, &chanconfig);
-
- if ((res = gpakTearDownChannel(vpm150m->dspid, i, &tstatus))) {
- goto vpm_bh_out;
- }
-
- if ((res = gpakConfigureChannel(vpm150m->dspid, i, tdmToTdm, &chanconfig, &cstatus))) {
- goto vpm_bh_out;
- }
-
- if (!vpm150m->desiredecstate[i].tap_length)
- res = gpakAlgControl(vpm150m->dspid, i, BypassEcanA, &pstatus);
-
- } else if (vpm150m->desiredecstate[i].tap_length != vpm150m->curecstate[i].tap_length) {
- if (vpm150m->desiredecstate[i].tap_length) {
- res = gpakAlgControl(vpm150m->dspid, i, EnableEcanA, &pstatus);
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "Echocan enable took %d ms\n", wc->intcount - start);
- } else {
- res = gpakAlgControl(vpm150m->dspid, i, BypassEcanA, &pstatus);
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "Echocan disable took %d ms\n", wc->intcount - start);
- }
- }
-
-vpm_bh_out:
- if (!res)
- vpm150m->curecstate[i] = vpm150m->desiredecstate[i];
- }
-
- return;
-}
-
-static int vpm150m_config_hw(struct wctdm *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 = SlotCfg2Groups;
- portconfig.FirstBlockNum2 = 0;
- portconfig.FirstSlotMask2 = 0xffff;
- portconfig.SecBlockNum2 = 1;
- portconfig.SecSlotMask2 = 0xffff;
- portconfig.SerialWordSize2 = SerWordSize8;
- portconfig.CompandingMode2 = cmpNone;
- portconfig.TxFrameSyncPolarity2 = FrameSyncActHigh;
- portconfig.RxFrameSyncPolarity2 = FrameSyncActHigh;
- portconfig.TxClockPolarity2 = SerClockActHigh;
- portconfig.RxClockPolarity2 = SerClockActLow;
- portconfig.TxDataDelay2 = DataDelay0;
- portconfig.RxDataDelay2 = DataDelay0;
- portconfig.DxDelay2 = Disabled;
- portconfig.ThirdSlotMask2 = 0x0000;
- portconfig.FouthSlotMask2 = 0x0000;
- portconfig.FifthSlotMask2 = 0x0000;
- portconfig.SixthSlotMask2 = 0x0000;
- portconfig.SevenSlotMask2 = 0x0000;
- portconfig.EightSlotMask2 = 0x0000;
-
- /* Third Serial Port Config */
- portconfig.SlotsSelect3 = SlotCfg2Groups;
- portconfig.FirstBlockNum3 = 0;
- portconfig.FirstSlotMask3 = 0xffff;
- portconfig.SecBlockNum3 = 1;
- portconfig.SecSlotMask3 = 0xffff;
- 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 = 0x0000;
- portconfig.FouthSlotMask3 = 0x0000;
- portconfig.FifthSlotMask3 = 0x0000;
- portconfig.SixthSlotMask3 = 0x0000;
- portconfig.SevenSlotMask3 = 0x0000;
- portconfig.EightSlotMask3 = 0x0000;
-
- if ((configportstatus = gpakConfigurePorts(vpm150m->dspid, &portconfig, &pstatus))) {
- printk(KERN_NOTICE "Configuration of ports failed (%d)!\n", configportstatus);
- return -1;
- } else {
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "Configured McBSP ports successfully\n");
- }
-
- if ((res = gpakPingDsp(vpm150m->dspid, &vpm150m->version))) {
- printk(KERN_NOTICE "Error pinging DSP (%d)\n", res);
- return -1;
- }
-
- for (i = 0; i < wc->type; i++) {
- vpm150m->curecstate[i].tap_length = 0;
- vpm150m->curecstate[i].nlp_type = vpmnlptype;
- vpm150m->curecstate[i].nlp_threshold = vpmnlpthresh;
- vpm150m->curecstate[i].nlp_max_suppress = vpmnlpmaxsupp;
-
- vpm150m->desiredecstate[i].tap_length = 0;
- vpm150m->desiredecstate[i].nlp_type = vpmnlptype;
- vpm150m->desiredecstate[i].nlp_threshold = vpmnlpthresh;
- vpm150m->desiredecstate[i].nlp_max_suppress = vpmnlpmaxsupp;
-
- vpm150m_set_chanconfig_from_state(&vpm150m->curecstate[i], i, &chanconfig);
-
- if ((res = gpakConfigureChannel(vpm150m->dspid, i, tdmToTdm, &chanconfig, &cstatus))) {
- printk(KERN_NOTICE "Unable to configure channel (%d)", res);
- if (res == 1) {
- printk(", reason %d", cstatus);
- }
- printk("\n");
-
- return -1;
- }
-
- if ((res = gpakAlgControl(vpm150m->dspid, i, BypassEcanA, &algstatus))) {
- printk(KERN_NOTICE "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))) {
- printk(KERN_NOTICE "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))) {
- printk(KERN_NOTICE "Error pinging DSP (%d)\n", res);
- return -1;
- }
-
- vpm150m->wq = create_singlethread_workqueue("wctdm24xxp");
- vpm150m->wc = wc;
-
- if (!vpm150m->wq) {
- printk(KERN_NOTICE "Unable to create work queue!\n");
- return -1;
- }
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- INIT_WORK(&vpm150m->work, vpm150m_bh, vpm150m);
-#else
- INIT_WORK(&vpm150m->work, vpm150m_bh);
-#endif
-
- /* Turn on DTMF detection */
- if (vpmdtmfsupport)
- set_bit(VPM150M_DTMFDETECT, &vpm150m->control);
-
- set_bit(VPM150M_ACTIVE, &vpm150m->control);
-
- return 0;
-}
-#endif /* VPM150M_SUPPORT */
-
-enum vpmadt032_init_result {
- VPMADT032_SUCCESS,
- VPMADT032_NOT_FOUND,
- VPMADT032_FAILED,
- VPMADT032_DISABLED,
-};
-
-static enum vpmadt032_init_result wctdm_vpm150m_init(struct wctdm *wc)
-{
- unsigned short i;
- struct vpm150m *vpm150m;
- unsigned short reg;
- unsigned long flags;
- enum vpmadt032_init_result res = VPMADT032_FAILED;
-
-#ifdef VPM150M_SUPPORT
- struct wctdm_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
- gpakDownloadStatus_t downloadstatus;
- gpakPingDspStat_t pingstatus;
-#endif
-
- if (!vpmsupport) {
- printk(KERN_NOTICE "VPM: Support Disabled\n");
- wc->vpm150m = NULL;
- return VPMADT032_DISABLED;
- }
-
- vpm150m = kmalloc(sizeof(struct vpm150m), GFP_KERNEL);
-
- if (!vpm150m) {
- printk(KERN_NOTICE "Unable to allocate VPM150M!\n");
- return VPMADT032_FAILED;
- }
-
- memset(vpm150m, 0, sizeof(struct vpm150m));
-
- /* Init our vpm150m struct */
- sema_init(&vpm150m->sem, 1);
- vpm150m->curpage = 0x80;
-
- for (i = 0; i < WC_MAX_IFACES; i++) {
- if (ifaces[i] == wc)
- vpm150m->dspid = i;
- }
-
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "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++)
- schluffen(&wc->regq);
-
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "VPMADT032 Testing page access: ");
- for (i = 0; i < 0xf; i++) {
- int x;
- for (x = 0; x < 3; x++) {
- wctdm_vpm150m_setpage(wc, i);
- reg = wctdm_vpm150m_getpage(wc);
- if (reg != i) {
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "Failed: Sent %x != %x VPMADT032 Failed HI page test\n", i, reg);
- res = VPMADT032_NOT_FOUND;
- goto failed_exit;
- }
- }
- }
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "Passed\n");
-
- /* Set us up to page 0 */
- wctdm_vpm150m_setpage(wc, 0);
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "VPMADT032 now doing address test: ");
- for (i = 0; i < 16; i++) {
- int x;
- for (x = 0; x < 2; x++) {
- wctdm_vpm150m_setreg(wc, 1, 0x1000, &i);
- wctdm_vpm150m_getreg(wc, 1, 0x1000, &reg);
- if (reg != i) {
- printk("VPMADT032 Failed address test\n");
- goto failed_exit;
- }
-
- }
- }
- if (debug & DEBUG_ECHOCAN)
- printk("Passed\n");
-
-#ifndef VPM150M_SUPPORT
- printk(KERN_NOTICE "Found VPMADT032 module but it is not able to function in anything less than a version 2.6 kernel\n");
- printk(KERN_NOTICE "Please update your kernel to a 2.6 or later kernel to enable it\n");
- goto failed_exit;
-#else
-
-#if 0
- /* Load the firmware */
- set_bit(VPM150M_SPIRESET, &vpm150m->control);
-
- /* Wait for it to boot */
- msleep(7000);
-
- pingstatus = gpakPingDsp(vpm150m->dspid, &version);
-
- if (pingstatus || (version != 0x106)) {
-#endif
-#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))
- schluffen(&wc->regq);
-
- printk(KERN_INFO "VPMADT032 Loading firmware... ");
- downloadstatus = gpakDownloadDsp(vpm150m->dspid, &fw);
-
- if (firmware != &embedded_firmware)
- release_firmware(firmware);
-
- if (downloadstatus != 0) {
- printk("Unable to download firmware to VPMADT032 with cause %d\n", downloadstatus);
- goto failed_exit;
- } else {
- printk("Success\n");
- }
-
- set_bit(VPM150M_SWRESET, &vpm150m->control);
-
- while (test_bit(VPM150M_SWRESET, &vpm150m->control))
- schluffen(&wc->regq);
-
-#if 0
- }
-#endif
-
- pingstatus = gpakPingDsp(vpm150m->dspid, &vpm150m->version);
-
- if (!pingstatus) {
- if (debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "Version of DSP is %x\n", vpm150m->version);
- } else {
- printk(KERN_NOTICE "VPMADT032 Failed! Unable to ping the DSP (%d)!\n", pingstatus);
- goto failed_exit;
- }
-
- if (vpm150m_config_hw(wc)) {
- goto failed_exit;
- }
-
- return VPMADT032_SUCCESS;
-#endif /* VPM150M_SUPPORT */
-
-failed_exit:
- spin_lock_irqsave(&wc->reglock, flags);
- wc->vpm150m = NULL;
- spin_unlock_irqrestore(&wc->reglock, flags);
- kfree(vpm150m);
-
- return res;
-}
-
-static void wctdm_vpm_set_dtmf_threshold(struct wctdm *wc, unsigned int threshold)
-{
- unsigned int x;
-
- for (x = 0; x < 4; x++) {
- wctdm_vpm_out(wc, x, 0xC4, (threshold >> 8) & 0xFF);
- wctdm_vpm_out(wc, x, 0xC5, (threshold & 0xFF));
- }
- printk(KERN_INFO "VPM: DTMF threshold set to %d\n", threshold);
-}
-
-static void wctdm_vpm_init(struct wctdm *wc)
+static int wctdm_vpm_init(struct wctdm *wc)
{
unsigned char reg;
unsigned int mask;
@@ -3697,20 +3228,14 @@ static void wctdm_vpm_init(struct wctdm *wc)
unsigned char vpmver=0;
unsigned int i, x, y;
- if (!vpmsupport) {
- printk(KERN_INFO "VPM: Support Disabled\n");
- wc->vpm = 0;
- return;
- }
-
for (x=0;x<NUM_EC;x++) {
ver = wctdm_vpm_in(wc, x, 0x1a0); /* revision */
if (debug & DEBUG_ECHOCAN)
printk(KERN_DEBUG "VPM100: Chip %d: ver %02x\n", x, ver);
if (ver != 0x33) {
printk(KERN_DEBUG "VPM100: %s\n", x ? "Inoperable" : "Not Present");
- wc->vpm = 0;
- return;
+ wc->vpm100 = 0;
+ return -ENODEV;
}
if (!x) {
@@ -3801,13 +3326,13 @@ static void wctdm_vpm_init(struct wctdm *wc)
wctdm_vpm_out(wc, x, i, 0xff);
}
- /* set DTMF detection threshold */
- wctdm_vpm_set_dtmf_threshold(wc, dtmfthreshold);
- if (vpmver == 0x01)
- wc->vpm = 2;
- else
- wc->vpm = 1;
+ /* TODO: What do the different values for vpm100 mean? */
+ if (vpmver == 0x01) {
+ wc->vpm100 = 2;
+ } else {
+ wc->vpm100 = 1;
+ }
printk(KERN_INFO "Enabling VPM100 gain adjustments on any FXO ports found\n");
for (i = 0; i < wc->type; i++) {
@@ -3822,9 +3347,79 @@ static void wctdm_vpm_init(struct wctdm *wc)
}
}
+ return 0;
}
-#endif
+static void get_default_portconfig(GpakPortConfig_t *portconfig)
+{
+ 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 = SlotCfg2Groups;
+ portconfig->FirstBlockNum2 = 0;
+ portconfig->FirstSlotMask2 = 0xffff;
+ portconfig->SecBlockNum2 = 1;
+ portconfig->SecSlotMask2 = 0xffff;
+ portconfig->SerialWordSize2 = SerWordSize8;
+ portconfig->CompandingMode2 = cmpNone;
+ portconfig->TxFrameSyncPolarity2 = FrameSyncActHigh;
+ portconfig->RxFrameSyncPolarity2 = FrameSyncActHigh;
+ portconfig->TxClockPolarity2 = SerClockActHigh;
+ portconfig->RxClockPolarity2 = SerClockActLow;
+ portconfig->TxDataDelay2 = DataDelay0;
+ portconfig->RxDataDelay2 = DataDelay0;
+ portconfig->DxDelay2 = Disabled;
+ portconfig->ThirdSlotMask2 = 0x0000;
+ portconfig->FouthSlotMask2 = 0x0000;
+ portconfig->FifthSlotMask2 = 0x0000;
+ portconfig->SixthSlotMask2 = 0x0000;
+ portconfig->SevenSlotMask2 = 0x0000;
+ portconfig->EightSlotMask2 = 0x0000;
+
+ /* Third Serial Port Config */
+ portconfig->SlotsSelect3 = SlotCfg2Groups;
+ portconfig->FirstBlockNum3 = 0;
+ portconfig->FirstSlotMask3 = 0xffff;
+ portconfig->SecBlockNum3 = 1;
+ portconfig->SecSlotMask3 = 0xffff;
+ 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 = 0x0000;
+ portconfig->FouthSlotMask3 = 0x0000;
+ portconfig->FifthSlotMask3 = 0x0000;
+ portconfig->SixthSlotMask3 = 0x0000;
+ portconfig->SevenSlotMask3 = 0x0000;
+ portconfig->EightSlotMask3 = 0x0000;
+}
static int wctdm_locate_modules(struct wctdm *wc)
{
@@ -3838,11 +3433,9 @@ static int wctdm_locate_modules(struct wctdm *wc)
wc->span.irqmisses = 0;
for (x=0;x<wc->cards;x++)
wc->modtype[x] = MOD_TYPE_FXSINIT;
-#ifdef VPM_SUPPORT
- wc->vpm = -1;
+ wc->vpm100 = -1;
for (x = wc->cards; x < wc->cards+NUM_EC; x++)
wc->modtype[x] = MOD_TYPE_VPM;
-#endif
spin_unlock_irqrestore(&wc->reglock, flags);
/* Wait just a bit */
for (x=0;x<10;x++)
@@ -3926,40 +3519,61 @@ retry:
}
}
}
-#ifdef VPM_SUPPORT
- wctdm_vpm_init(wc);
- if (wc->vpm) {
- printk(KERN_INFO "VPM: Present and operational (Rev %c)\n", 'A' + wc->vpm - 1);
+
+ if (!vpmsupport) {
+ printk(KERN_NOTICE "VPM: Support Disabled\n");
+ } else if (!wctdm_vpm_init(wc)) {
+ printk(KERN_INFO "VPM: Present and operational (Rev %c)\n", 'A' + wc->vpm100 - 1);
wc->ctlreg |= 0x10;
} else {
- enum vpmadt032_init_result res;
+ int res;
+ struct vpmadt032_options options;
+ GpakPortConfig_t portconfig;
+
spin_lock_irqsave(&wc->reglock, flags);
for (x = NUM_CARDS; x < NUM_CARDS + NUM_EC; x++)
wc->modtype[x] = MOD_TYPE_NONE;
spin_unlock_irqrestore(&wc->reglock, flags);
- res = wctdm_vpm150m_init(wc);
+
+ options.debug = debug;
+ options.vpmnlptype = vpmnlptype;
+ options.vpmnlpthresh = vpmnlpthresh;
+ options.vpmnlpmaxsupp = vpmnlpmaxsupp;
+
+ if (!(wc->vpmadt032=vpmadt032_alloc(&options))) {
+ return -ENOMEM;
+ }
+ wc->vpmadt032->setchanconfig_from_state = setchanconfig_from_state;
+ wc->vpmadt032->context = wc;
+ wc->vpmadt032->span = &wc->span;
+ get_default_portconfig(&portconfig);
+ res = vpmadt032_init(wc->vpmadt032, wc->vb);
/* In case there was an error while we were loading the VPM module. */
if (voicebus_current_latency(wc->vb) > startinglatency) {
+ vpmadt032_free(wc->vpmadt032);
+ wc->vpmadt032 = NULL;
return -EAGAIN;
}
- switch (res) {
- case VPMADT032_SUCCESS:
- printk(KERN_INFO "VPMADT032: Present and operational (Firmware version %x)\n", wc->vpm150m->version);
- wc->ctlreg |= 0x10;
- break;
- case VPMADT032_DISABLED:
- case VPMADT032_NOT_FOUND:
- /* nothing */
- break;
- default:
- return -EIO;
+ if (res) {
+ vpmadt032_free(wc->vpmadt032);
+ wc->vpmadt032 = NULL;
+ return res;
+ }
+
+ /* Now we need to configure the VPMADT032 module for this
+ * particular board. */
+ res = config_vpmadt032(wc->vpmadt032);
+ if (res) {
+ vpmadt032_free(wc->vpmadt032);
+ wc->vpmadt032 = NULL;
+ return res;
}
+
+ printk(KERN_INFO "VPMADT032: Present and operational (Firmware version %x)\n", wc->vpmadt032->version);
+ /* TODO what is 0x10 in this context? */
+ wc->ctlreg |= 0x10;
}
-#endif
- /* In case there was an error while we were loading the VPM module. */
- if (voicebus_current_latency(wc->vb) > startinglatency) {
- return -EAGAIN;
- }
+
return 0;
}
@@ -4112,40 +3726,30 @@ static void wctdm_release(struct wctdm *wc)
static void __devexit wctdm_remove_one(struct pci_dev *pdev)
{
struct wctdm *wc = pci_get_drvdata(pdev);
-
-#ifdef VPM150M_SUPPORT
- unsigned long flags;
- struct vpm150m *vpm150m = wc->vpm150m;
-#endif
+ struct vpmadt032 *vpm = wc->vpmadt032;
if (wc) {
-
-#ifdef VPM150M_SUPPORT
- if (vpm150m) {
- clear_bit(VPM150M_DTMFDETECT, &vpm150m->control);
- clear_bit(VPM150M_ACTIVE, &vpm150m->control);
- flush_workqueue(vpm150m->wq);
- destroy_workqueue(vpm150m->wq);
+ if (vpm) {
+ clear_bit(VPM150M_DTMFDETECT, &vpm->control);
+ clear_bit(VPM150M_ACTIVE, &vpm->control);
+ flush_scheduled_work();
}
-#endif
+
voicebus_stop(wc->vb);
-#ifdef VPM150M_SUPPORT
- if (vpm150m) {
- spin_lock_irqsave(&wc->reglock, flags);
- wc->vpm150m = NULL;
- vpm150m->wc = NULL;
- spin_unlock_irqrestore(&wc->reglock, flags);
- kfree(wc->vpm150m);
+ if (vpm) {
+ vpmadt032_free(wc->vpmadt032);
+ wc->vpmadt032 = NULL;
}
-#endif
+
/* Release span, possibly delayed */
if (!wc->usecount) {
wctdm_release(wc);
printk(KERN_INFO "Freed a Wildcard\n");
}
- else
+ else {
wc->dead = 1;
+ }
}
}
@@ -4245,8 +3849,6 @@ module_param(neonmwi_envelope, int, 0600);
module_param(neonmwi_offlimit, int, 0600);
#ifdef VPM_SUPPORT
module_param(vpmsupport, int, 0600);
-module_param(vpmdtmfsupport, int, 0600);
-module_param(dtmfthreshold, int, 0600);
module_param(vpmnlptype, int, 0600);
module_param(vpmnlpthresh, int, 0600);
module_param(vpmnlpmaxsupp, int, 0600);
diff --git a/drivers/dahdi/wctdm24xxp/voicebus.c b/drivers/dahdi/wctdm24xxp/voicebus.c
deleted file mode 120000
index 6653619..0000000
--- a/drivers/dahdi/wctdm24xxp/voicebus.c
+++ /dev/null
@@ -1 +0,0 @@
-../voicebus.c \ No newline at end of file
diff --git a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
index f8da786..4bb90b7 100644
--- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
+++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
@@ -4,7 +4,7 @@
* Written by Mark Spencer <markster@digium.com>
* Support for TDM800P and VPM150M by Matthew Fredrickson <creslin@digium.com>
*
- * Copyright (C) 2005, 2006, Digium, Inc.
+ * Copyright (C) 2005-2009 Digium, Inc.
*
* All rights reserved.
*
@@ -28,7 +28,6 @@
#include <dahdi/kernel.h>
-#include "../voicebus.h"
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#include <linux/semaphore.h>
@@ -36,6 +35,8 @@
#include <asm/semaphore.h>
#endif
+#include "voicebus/voicebus.h"
+
#define NUM_FXO_REGS 60
#define WC_MAX_IFACES 128
@@ -76,8 +77,6 @@
#define SDI_DREAD (0x00040000)
#define SDI_DIN (0x00080000)
-#define PCI_WINDOW_SIZE ((2 * 2 * 2 * SFRAME_SIZE) + (2 * ERING_SIZE * 4))
-
#define __CMD_RD (1 << 20) /* Read Operation */
#define __CMD_WR (1 << 21) /* Write Operation */
#define __CMD_FIN (1 << 22) /* Has finished receive */
@@ -103,26 +102,11 @@
#define MAX_COMMANDS (USER_COMMANDS + ISR_COMMANDS)
-#define __VPM150M_RWPAGE (1 << 4)
-#define __VPM150M_RD (1 << 3)
-#define __VPM150M_WR (1 << 2)
-#define __VPM150M_FIN (1 << 1)
-#define __VPM150M_TX (1 << 0)
#define VPM150M_HPI_CONTROL 0x00
#define VPM150M_HPI_ADDRESS 0x02
#define VPM150M_HPI_DATA 0x03
-#define VPM150M_MAX_COMMANDS 8
-
-/* Some Bit ops for different operations */
-#define VPM150M_SPIRESET 0
-#define VPM150M_HPIRESET 1
-#define VPM150M_SWRESET 2
-#define VPM150M_DTMFDETECT 3
-#define VPM150M_ACTIVE 4
-
-#define VPM150M_MAX_DATA 1
#define VPM_SUPPORT
@@ -138,36 +122,8 @@
#endif
#ifdef VPM150M_SUPPORT
-#include "adt_lec.h"
-#endif
-
-struct vpm150m_cmd {
- unsigned int addr;
- unsigned char datalen;
- unsigned char desc;
- unsigned char txident;
- unsigned short data[VPM150M_MAX_DATA];
-};
-
-struct vpm150m {
-#ifdef VPM150M_SUPPORT
- struct workqueue_struct *wq;
- struct work_struct work;
+#include "voicebus/GpakCust.h"
#endif
- struct wctdm *wc;
-
- int dspid;
- struct semaphore sem;
- unsigned long control;
- unsigned char curpage;
- unsigned short version;
- struct adt_lec_params curecstate[24];
- struct adt_lec_params desiredecstate[24];
- unsigned long curdtmfmutestate;
- unsigned long desireddtmfmutestate;
- struct vpm150m_cmd cmdq[VPM150M_MAX_COMMANDS];
- unsigned char curtone[24];
-};
struct calregs {
unsigned char vals[NUM_CAL_REGS];
@@ -261,22 +217,22 @@ struct wctdm {
/* Set hook */
int sethook[NUM_CARDS + NUM_EC];
int dacssrc[NUM_CARDS];
+ /* Type is the maximum number of FXO/FXS ports supported */
int type;
-#ifdef VPM_SUPPORT
- int vpm;
+ int vpm100;
+
unsigned long dtmfactive;
unsigned long dtmfmask;
unsigned long dtmfmutemask;
short dtmfenergy[NUM_CARDS];
short dtmfdigit[NUM_CARDS];
- struct vpm150m *vpm150m;
+ struct vpmadt032 *vpmadt032;
#ifdef FANCY_ECHOCAN
int echocanpos;
int blinktimer;
#endif
-#endif
struct voicebus *vb;
struct dahdi_chan *chans[NUM_CARDS];
int initialized;
diff --git a/drivers/dahdi/wcte12xp/GpakApi.h b/drivers/dahdi/wcte12xp/GpakApi.h
deleted file mode 100644
index ebd440e..0000000
--- a/drivers/dahdi/wcte12xp/GpakApi.h
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Copyright (c) 2005 , Adaptive Digital Technologies, Inc.
- *
- * File Name: GpakApi.h
- *
- * Description:
- * This file contains the function prototypes and data types for the user
- * API functions that communicate with DSPs executing G.PAK software. The
- * file is used by application software in the host processor connected to
- * C55X G.PAK DSPs via a Host Port Interface.
- *
- * Version: 1.0
- *
- * Revision History:
- * 06/15/05 - Initial release.
- * 11/15/2006 - 24 TDM-TDM Channels EC release
- *
- * This program has been released under the terms of the GPL version 2 by
- * permission of Adaptive Digital Technologies, Inc.
- *
- */
-
-/*
- * 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.
- */
-
-#ifndef _GPAKAPI_H /* prevent multiple inclusion */
-#define _GPAKAPI_H
-#include "GpakErrs.h"
-#include "gpakenum.h"
-
-// Bit masks to select which algorithm's parameters to update: Or-together the
-// desired masks into the UpdateBits function parameter.
-#define DTMF_UPDATE_MASK 0x0010 // update DTMF params, MinLevel, SNRFlag and Freq
-#define DTMF_TWIST_UPDATE_MASK 0x0020 // update DTMF TWIST system params
-#define DTMF_VALID_MASK 0x0080 // update DTMF ValidMask params
-
-#define DSP_DEBUG_BUFF_SIZE 42 // units of 16-bit words
-
-/* Definition of an Asynchronous Event Data Structure */
-typedef union
-{
- struct
- {
- GpakToneCodes_t ToneCode; // detected tone code
- unsigned short int ToneDuration; // tone duration
- GpakTdmDirection Direction; // detected on A r B side
- short int DebugToneStatus;// reserved for debug info
- } toneEvent;
-
-} GpakAsyncEventData_t;
-
-/* Definition of an Echo Canceller Parameters information structure. */
-typedef struct
-{
- short int EcanTapLength; // Echo Can Num Taps (tail length)
- short int EcanNlpType; // Echo Can NLP Type
- short int EcanAdaptEnable; // Echo Can Adapt Enable flag
- short int EcanG165DetEnable; // Echo Can G165 Detect Enable flag
- short int EcanDblTalkThresh; // Echo Can Double Talk threshold
- short int EcanNlpThreshold; // Echo Can NLP threshold
- short int EcanNlpConv; // Dynamic NLP control, NLP limit when EC about to converged
- short int EcanNlpUnConv;// Dynamic NLP control, NLP limit when EC not converged yet
- short int EcanNlpMaxSuppress; // suppression level for NLP_SUPP mode
- short int EcanCngThreshold; // Echo Can CNG Noise threshold
- short int EcanAdaptLimit; // Echo Can Max Adapts per frame
- short int EcanCrossCorrLimit; // Echo Can Cross Correlation limit
- short int EcanNumFirSegments; // Echo Can Num FIR Segments
- short int EcanFirSegmentLen; // Echo Can FIR Segment Length
-} GpakEcanParms_t;
-
-/* Definition of a Channel Configuration information structure. */
-typedef struct
-{
- GpakSerialPort_t PcmInPortA; // A side PCM Input Serial Port Id
- unsigned short int PcmInSlotA; // A side PCM Input Time Slot
- GpakSerialPort_t PcmOutPortA; // A side PCM Output Serial Port Id
- unsigned short int PcmOutSlotA; // A side PCM Output Time Slot
- GpakSerialPort_t PcmInPortB; // B side PCM Input Serial Port Id
- unsigned short int PcmInSlotB; // B side PCM Input Time Slot
- GpakSerialPort_t PcmOutPortB; // B side PCM Output Serial Port Id
- unsigned short int PcmOutSlotB; // B side PCM Output Time Slot
- GpakToneTypes ToneTypesA; // A side Tone Detect Types
- GpakToneTypes ToneTypesB; // B side Tone Detect Types
- GpakActivation EcanEnableA; // Echo Cancel A Enabled
- GpakActivation EcanEnableB; // Echo Cancel B Enabled
- GpakEcanParms_t EcanParametersA; // Echo Cancel parameters
- GpakEcanParms_t EcanParametersB; // Echo Cancel parameters
- GpakCompandModes SoftwareCompand; // software companding
- GpakRate_t FrameRate; // Gpak Frame Rate
- GpakActivation MuteToneA; // A side mute DTMF Enabled
- GpakActivation MuteToneB; // B side mute DTMF Enabled
- GpakActivation FaxCngDetA; // A side FaxCng Tone Detector Enabled
- GpakActivation FaxCngDetB; // B side FaxCng Tone Detector Enabled
-
-} GpakChannelConfig_t;
-
-
-/* Definition of a Serial Port Configuration Structure */
-typedef struct
-{
- GpakSlotCfg_t SlotsSelect1; // port 1 Slot selection
- unsigned short int FirstBlockNum1; // port 1 first group Block Number
- unsigned short int FirstSlotMask1; // port 1 first group Slot Mask
- unsigned short int SecBlockNum1; // port 1 second group Block Number
- unsigned short int SecSlotMask1; // port 1 second group Slot Mask
-
- GpakSerWordSize_t SerialWordSize1; // port 1 serial word size
- GpakCompandModes CompandingMode1; // port 1 companding mode
- GpakSerFrameSyncPol_t TxFrameSyncPolarity1; // port 1 Tx Frame Sync Polarity
- GpakSerFrameSyncPol_t RxFrameSyncPolarity1; // port 1 Rx Frame Sync Polarity
- GpakSerClockPol_t TxClockPolarity1; // port 1 Tx Clock Polarity
- GpakSerClockPol_t RxClockPolarity1; // port 1 Rx Clock Polarity
- GpakSerDataDelay_t TxDataDelay1; // port 1 Tx data delay
- GpakSerDataDelay_t RxDataDelay1; // port 1 Rx data delay
- GpakActivation DxDelay1; // port 1 DX Delay
-
- unsigned short int ThirdSlotMask1; // port 1 3rd group Slot Mask
- unsigned short int FouthSlotMask1; // port 1 4th group Slot Mask
- unsigned short int FifthSlotMask1; // port 1 5th group Slot Mask
- unsigned short int SixthSlotMask1; // port 1 6th group Slot Mask
- unsigned short int SevenSlotMask1; // port 1 7th group Slot Mask
- unsigned short int EightSlotMask1; // port 1 8th group Slot Mask
-
-
- GpakSlotCfg_t SlotsSelect2; // port 2 Slot selection
- unsigned short int FirstBlockNum2; // port 2 first group Block Number
- unsigned short int FirstSlotMask2; // port 2 first group Slot Mask
- unsigned short int SecBlockNum2; // port 2 second group Block Number
- unsigned short int SecSlotMask2; // port 2 second group Slot Mask
- GpakSerWordSize_t SerialWordSize2; // port 2 serial word size
- GpakCompandModes CompandingMode2; // port 2 companding mode
- GpakSerFrameSyncPol_t TxFrameSyncPolarity2; // port 2 Tx Frame Sync Polarity
- GpakSerFrameSyncPol_t RxFrameSyncPolarity2; // port 2 Rx Frame Sync Polarity
- GpakSerClockPol_t TxClockPolarity2; // port 2 Tx Clock Polarity
- GpakSerClockPol_t RxClockPolarity2; // port 2 Rx Clock Polarity
- GpakSerDataDelay_t TxDataDelay2; // port 2 Tx data delay
- GpakSerDataDelay_t RxDataDelay2; // port 2 Rx data delay
- GpakActivation DxDelay2; // port 2 DX Delay
-
- unsigned short int ThirdSlotMask2; // port 2 3rd group Slot Mask
- unsigned short int FouthSlotMask2; // port 2 4th group Slot Mask
- unsigned short int FifthSlotMask2; // port 2 5th group Slot Mask
- unsigned short int SixthSlotMask2; // port 2 6th group Slot Mask
- unsigned short int SevenSlotMask2; // port 2 7th group Slot Mask
- unsigned short int EightSlotMask2; // port 2 8th group Slot Mask
-
- GpakSlotCfg_t SlotsSelect3; // port 3 Slot selection
- unsigned short int FirstBlockNum3; // port 3 first group Block Number
- unsigned short int FirstSlotMask3; // port 3 first group Slot Mask
- unsigned short int SecBlockNum3; // port 3 second group Block Number
- unsigned short int SecSlotMask3; // port 3 second group Slot Mask
- GpakSerWordSize_t SerialWordSize3; // port 3 serial word size
- GpakCompandModes CompandingMode3; // port 3 companding mode
- GpakSerFrameSyncPol_t TxFrameSyncPolarity3; // port 3 Tx Frame Sync Polarity
- GpakSerFrameSyncPol_t RxFrameSyncPolarity3; // port 3 Rx Frame Sync Polarity
- GpakSerClockPol_t TxClockPolarity3; // port 3 Tx Clock Polarity
- GpakSerClockPol_t RxClockPolarity3; // port 3 Rx Clock Polarity
- GpakSerDataDelay_t TxDataDelay3; // port 3 Tx data delay
- GpakSerDataDelay_t RxDataDelay3; // port 3 Rx data delay
- GpakActivation DxDelay3; // port 3 DX Delay
-
- unsigned short int ThirdSlotMask3; // port 3 3rd group Slot Mask
- unsigned short int FouthSlotMask3; // port 3 4th group Slot Mask
- unsigned short int FifthSlotMask3; // port 3 5th group Slot Mask
- unsigned short int SixthSlotMask3; // port 3 6th group Slot Mask
- unsigned short int SevenSlotMask3; // port 3 7th group Slot Mask
- unsigned short int EightSlotMask3; // port 3 8th group Slot Mask
-
-} GpakPortConfig_t;
-
-/* Definition of a Tone Generation Parameter Structure */
-/*
-typedef struct
-{
- GpakToneGenType_t ToneType; // Tone Type
- unsigned short int Frequency[4]; // Frequency (Hz)
- short int Level[4]; // Frequency's Level (1 dBm)
- unsigned short int OnTime[4]; // On Times (msecs)
- unsigned short int OffTime[4]; // Off Times (msecs)
-} GpakToneGenParms_t;
-*/
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* gpakConfigureChannel return status. */
-typedef enum
-{
- CcsSuccess = 0, /* Channel Configured successfully */
- CcsParmError = 1, /* Channel Config Parameter error */
- CcsInvalidChannel = 2, /* invalid channel */
- CcsInvalidDsp = 3, /* invalid DSP */
- CcsDspCommFailure = 4 /* failed to communicate with DSP */
-} gpakConfigChanStatus_t;
-
-/*
- * gpakConfigureChannel - Configure a DSP's Channel.
- *
- * FUNCTION
- * This function configures a DSP's Channel.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-extern gpakConfigChanStatus_t gpakConfigureChannel(
- unsigned short int DspId, // DSP identifier
- unsigned short int ChannelId, // channel identifier
- GpakChanType ChannelType, // channel type
- GpakChannelConfig_t *pChanConfig, // pointer to channel config info
- GPAK_ChannelConfigStat_t *pStatus // pointer to Channel Config Status
- );
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* gpakTearDownChannel return status. */
-typedef enum
-{
- TdsSuccess = 0, /* Channel Tear Down successful */
- TdsError = 1, /* Channel Tear Down error */
- TdsInvalidChannel = 2, /* invalid channel */
- TdsInvalidDsp = 3, /* invalid DSP */
- TdsDspCommFailure = 4 /* failed to communicate with DSP */
-} gpakTearDownStatus_t;
-
-/*
- * gpakTearDownChannel - Tear Down a DSP's Channel.
- *
- * FUNCTION
- * This function tears down a DSP's Channel.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-
-extern gpakTearDownStatus_t gpakTearDownChannel(
- unsigned short int DspId, // DSP identifier
- unsigned short int ChannelId, // channel identifier
- GPAK_TearDownChanStat_t *pStatus // pointer to Tear Down Status
- );
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* gpakAlgControl return status. */
-typedef enum
-{
- AcSuccess = 0, /* control successful */
- AcInvalidChannel = 1, /* invalid channel identifier */
- AcInvalidDsp = 2, /* invalid DSP */
- AcParmError = 3, /* invalid control parameter */
- AcDspCommFailure = 4 /* failed to communicate with DSP */
-} gpakAlgControlStat_t;
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakAlgControl - Control an Algorithm.
- *
- * FUNCTION
- * This function controls an Algorithm
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-extern gpakAlgControlStat_t gpakAlgControl(
- unsigned short int DspId, // DSP identifier
- unsigned short int ChannelId, // channel identifier
- GpakAlgCtrl_t ControlCode, // algorithm control code
- GPAK_AlgControlStat_t *pStatus // pointer to return status
- );
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* gpakConfigurePorts return status. */
-typedef enum
-{
- CpsSuccess = 0, /* Serial Ports configured successfully */
- CpsParmError = 1, /* Configure Ports Parameter error */
- CpsInvalidDsp = 2, /* invalid DSP */
- CpsDspCommFailure = 3 /* failed to communicate with DSP */
-} gpakConfigPortStatus_t;
-
-/*
- * gpakConfigurePorts - Configure a DSP's serial ports.
- *
- * FUNCTION
- * This function configures a DSP's serial ports.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-extern gpakConfigPortStatus_t gpakConfigurePorts(
- unsigned short int DspId, // DSP identifier
- GpakPortConfig_t *pPortConfig, // pointer to Port Config info
- GPAK_PortConfigStat_t *pStatus // pointer to Port Config Status
- );
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* gpakDownloadDsp return status. */
-typedef enum
-{
- GdlSuccess = 0, /* DSP download successful */
- GdlFileReadError = 1, /* error reading Download file */
- GdlInvalidFile = 2, /* invalid Download file content */
- GdlInvalidDsp = 3 /* invalid DSP */
-} gpakDownloadStatus_t;
-
-/*
- * gpakDownloadDsp - Download a DSP's Program and initialized Data memory.
- *
- * FUNCTION
- * This function reads a DSP's Program and Data memory image from the
- * specified file and writes the image to the DSP's memory.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- */
-extern gpakDownloadStatus_t gpakDownloadDsp(
- unsigned short int DspId, // DSP identifier
- GPAK_FILE_ID FileId // G.PAK download file identifier
- );
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-/* gpakReadEventFIFOMessage return status */
-typedef enum
-{
- RefEventAvail = 0, /* an event was successfully read from the fifo */
- RefNoEventAvail = 1, /* no event was in the fifo */
- RefInvalidDsp = 2, /* invalid DSP identifier */
- RefInvalidEvent = 3, /* invalid event */
- RefDspCommFailure = 4 /* error communicating with DSP */
-} gpakReadEventFIFOMessageStat_t;
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakReadEventFIFOMessage - read from the event fifo
- *
- * FUNCTION
- * This function reads a single event from the event fifo if one is available
- *
- * RETURNS
- * Status code indicating success or a specific error.
- *
- * Note: This function should be called in a loop until the return status
- * indicates that the fifo is empty.
- */
-extern gpakReadEventFIFOMessageStat_t gpakReadEventFIFOMessage(
- unsigned short int DspId, // DSP identifier
- unsigned short int *pChannelId, // pointer to channel identifier
- GpakAsyncEventCode_t *pEventCode, // pointer to Event Code
- GpakAsyncEventData_t *pEventData // pointer to Event Data Struct
- );
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
-/* gpakPingDsp return status values */
-typedef enum
-{
- PngSuccess = 0, /* DSP responded successfully */
- PngInvalidDsp = 1, /* invalid DSP identifier */
- PngDspCommFailure = 2 /* error communicating with DSP */
-} gpakPingDspStat_t;
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakPingDsp - ping the DSP to see if it's alive
- *
- * FUNCTION
- * This function checks if the DSP is still communicating with the host
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-extern gpakPingDspStat_t gpakPingDsp(
- unsigned short int DspId, // DSP identifier
- unsigned short int *pDspSwVersion // DSP software version
- );
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
-/* gpakSerialTxFixedValue return status values */
-typedef enum
-{
- TfvSuccess = 0, /* operation successful */
- TfvInvalidChannel = 1, /* invalid channel identifier */
- TfvInvalidDsp = 2, /* invalid DSP identifier */
- TfvDspCommFailure = 3 /* failed to communicate with DSP */
-} gpakSerialTxFixedValueStat_t;
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakSerialTxFixedValue - transmit a fixed value on a timeslot
- *
- * FUNCTION
- * This function controls transmission of a fixed value out onto a serial
- * port's timeslot.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-extern gpakSerialTxFixedValueStat_t gpakSerialTxFixedValue(
- unsigned short int DspId, // DSP identifier
- unsigned short int ChannelId, // channel identifier
- GpakSerialPort_t PcmOutPort, // PCM Output Serial Port Id
- unsigned short int PcmOutSlot, // PCM Output Time Slot
- unsigned short int Value, // 16-bit value
- GpakActivation State // activation state
- );
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
-/* gpakControlTdmLoopBack return status values */
-typedef enum
-{
- ClbSuccess = 0, /* operation successful */
- ClbSerPortInactive = 1, /* serial port is inactive */
- ClbInvalidDsp = 2, /* invalid DSP identifier */
- ClbDspCommFailure = 3 /* failed to communicate with DSP */
-} gpakControlTdmLoopBackStat_t;
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakControlTdmLoopBack - control a serial port's loopback state
- *
- * FUNCTION
- * This function enables/disables the tdm input to output looback mode on a
- * serial port
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-gpakControlTdmLoopBackStat_t gpakControlTdmLoopBack(
- unsigned short int DspId, // DSP identifier
- GpakSerialPort_t SerialPort, // Serial Port Id
- GpakActivation LoopBackState // Loopback State
- );
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
-/* gpakReadCpuUsage return status values */
-typedef enum
-{
- RcuSuccess = 0, /* operation successful */
- RcuInvalidDsp = 1, /* invalid DSP identifier */
- RcuDspCommFailure = 2 /* communication failure */
-} gpakReadCpuUsageStat_t;
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakReadCpuUsage - read the cpu usage statistics
- *
- * FUNCTION
- * This function reads cpu utilization from the DSP.
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-extern gpakReadCpuUsageStat_t gpakReadCpuUsage(
- unsigned short int DspId, // DSP identifier
- unsigned short int *pPeakUsage, // pointer to peak usage variable
- unsigned short int *pPrev1SecPeakUsage // peak usage over previous 1 second
- );
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
-/* gpakResetCpuUsageStats return status values */
-typedef enum
-{
- RstcSuccess = 0, /* operation successful */
- RstcInvalidDsp = 1, /* invalid DSP identifier */
- RstcDspCommFailure = 2 /* communication failure */
-} gpakResetCpuUsageStat_t;
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakResetCpuUsageStats - reset the cpu usage statistics
- *
- * FUNCTION
- * This function resets the cpu utilization statistics
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-extern gpakResetCpuUsageStat_t gpakResetCpuUsageStats(
- unsigned short int DspId // DSP identifier
- );
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
-/* gpakReadFramingStats return status values */
-typedef enum
-{
- RfsSuccess = 0, /* operation successful */
- RfsInvalidDsp = 1, /* invalid DSP identifier */
- RfsDspCommFailure = 2 /* communication failure */
-} gpakReadFramingStatsStatus_t;
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakReadFramingStats
- *
- * FUNCTION
- * This function reads a DSP's framing interrupt statistics
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-extern gpakReadFramingStatsStatus_t gpakReadFramingStats(
- unsigned short int DspId, // DSP identifier
- unsigned short int *pFramingError1Count, // port 1 Framing error count
- unsigned short int *pFramingError2Count, // port 2 Framing error count
- unsigned short int *pFramingError3Count, // port 3 Framing error count
- unsigned short int *pDmaStopErrorCount, // DMA-stoppage error count
- unsigned short int *pDmaSlipStatsBuffer // DMA slips count
- );
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
-/* gpakResetFramingStats return values */
-typedef enum
-{
- RstfSuccess = 0, /* operation successful */
- RstfInvalidDsp = 1, /* invalid DSP identifier */
- RstfDspCommFailure = 2 /* communication failure */
-} gpakResetFramingStatsStatus_t;
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakResetFramingStats - reset a DSP's framing interrupt statistics
- *
- * FUNCTION
- * This function resets a DSP's framing interrupt statistics
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-extern gpakResetFramingStatsStatus_t gpakResetFramingStats(
- unsigned short int DspId // DSP identifier
- );
-
-
-typedef enum
-{
- RmmSuccess =0,
- RmmInvalidDsp = 1,
- RmmSizeTooBig = 2,
- RmmFailure = 3,
- RmmInvalidAddress = 4
-
-} gpakReadDSPMemoryStat_t;
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * gpakResetFramingStats - read a section of DSP memory
- * to get access DSP registers, since 0x00--0x60 not HPI-accessable
- *
- * FUNCTION
- * This function resets a DSP's framing interrupt statistics
- *
- * RETURNS
- * Status code indicating success or a specific error.
- */
-
-extern gpakReadDSPMemoryStat_t gpakReadDSPMemoryMap(
- unsigned short int DspId, // Dsp Identifier
- unsigned short int *pDest, // Buffer on host to hold DSP memory map
- DSP_ADDRESS BufrBaseAddress, // DSP memory users want to read out
- unsigned short int MemoryLength_Word16 // Length of memory section read out, unit is 16-bit word
- );
-
-typedef enum
-{
- GPIOSuccess =0,
- GPIOInvalidDsp = 1,
- GPIODspCommFailure = 2
-}gpakAccessGPIOStat_t;
-
-extern gpakAccessGPIOStat_t gpakAccessGPIO(
- unsigned short int DspId, // DSP identifier
- GpakGPIOCotrol_t gpakControlGPIO,// select oeration, changeDIR/write/read
- unsigned short int *pGPIOValue // pointer for the read/write value or DIR mask
- );
-
-/* gpakWriteSystemParms return status. */
-typedef enum
-{
- WspSuccess = 0, /* System Parameters written successfully */
- WspParmError = 1, /* Write System Parms's Parameter error */
- WspInvalidDsp = 2, /* invalid DSP */
- WspDspCommFailure = 3 /* failed to communicate with DSP */
-} gpakWriteSysParmsStatus_t;
-
-/* Definition of a System Parameters information structure. */
-typedef struct
-{
- /* DTMF Parameters */
- short int MinSigLevel; /* 0 = Disabled, Min Sig Power Level for detection */
- short int SNRFlag; /* 0 = Disabled, relax SNR tolerances */
- short int FreqDeviation; /* 0 = Disabled, X Percent Deviation times 10 (e.g. 1.7% is entered as 17) */
- short int DtmfFwdTwist; /* 0 to 8 db */
- short int DtmfRevTwist; /* 0 to 8 db */
-
- short int DtmfValidityMask; /* This flag allows users to relax the trailing conditions of the tone */
-
-} GpakSystemParms_t;
-/* gpakReadSystemParms return status. */
-typedef enum
-{
- RspSuccess = 0, /* System Parameters read successfully */
- RspInvalidDsp = 1, /* invalid DSP */
- RspDspCommFailure = 2 /* failed to communicate with DSP */
-} gpakReadSysParmsStatus_t;
-
-extern gpakReadSysParmsStatus_t gpakReadSystemParms(
- unsigned short int DspId, // DSP identifier
- GpakSystemParms_t *pSysParms /* pointer to System Parms info var */
- );
-
-extern gpakWriteSysParmsStatus_t gpakWriteSystemParms(
- unsigned short int DspId, // DSP identifier
- GpakSystemParms_t *pSysParms, /* pointer to System Parms info var */
- unsigned short int UpdateBits, /* input: flags indicating which parms to update */
- GPAK_SysParmsStat_t *pStatus /* pointer to Write System Parms Status */
- );
-
-#endif // end multiple inclusion
-
diff --git a/drivers/dahdi/wcte12xp/GpakErrs.h b/drivers/dahdi/wcte12xp/GpakErrs.h
deleted file mode 100644
index 2f5083b..0000000
--- a/drivers/dahdi/wcte12xp/GpakErrs.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2002 - 2004, Adaptive Digital Technologies, Inc.
- *
- * File Name: GpakErrs.h
- *
- * Description:
- * This file contains DSP reply status codes used by G.PAK API functions to
- * indicate specific errors.
- *
- * Version: 1.0
- *
- * Revision History:
- * 10/17/01 - Initial release.
- * 07/03/02 - Updates for conferencing.
- * 06/15/04 - Tone type updates.
- *
- * This program has been released under the terms of the GPL version 2 by
- * permission of Adaptive Digital Technologies, Inc.
- *
- */
-
-/*
- * 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.
- */
-
-#ifndef _GPAKERRS_H /* prevent multiple inclusion */
-#define _GPAKERRS_H
-
-/* Configure Serial Ports reply status codes. */
-typedef enum
-{
- Pc_Success = 0, /* serial ports configured successfully */
- Pc_ChannelsActive = 1, /* unable to configure while channels active */
- Pc_TooManySlots1 = 2, /* too many slots selected for port 1 */
- Pc_InvalidBlockCombo1 = 3, /* invalid combination of blocks for port 1 */
- Pc_NoSlots1 = 4, /* no slots selected for port 1 */
- Pc_InvalidSlots1 = 5, /* invalid slot (> max) selected for port 1 */
- Pc_TooManySlots2 = 6, /* too many slots selected for port 2 */
- Pc_InvalidBlockCombo2 = 7, /* invalid combination of blocks for port 2 */
- Pc_NoSlots2 = 8, /* no slots selected for port 2 */
- Pc_InvalidSlots2 = 9, /* invalid slot (> max) selected for port 2 */
- Pc_TooManySlots3 = 10, /* too many slots selected for port 3 */
- Pc_InvalidBlockCombo3 = 11, /* invalid combination of blocks for port 3 */
- Pc_NoSlots3 = 12, /* no slots selected for port 3 */
- Pc_InvalidSlots3 = 13 /* invalid slot (> max) selected for port 3 */
-} GPAK_PortConfigStat_t;
-
-/* Configure Channel reply status codes. */
-typedef enum
-{
- Cc_Success = 0, /* channel configured successfully */
- Cc_InvalidChannelType = 1, /* invalid Channel Type */
- Cc_InvalidChannel = 2, /* invalid Channel A Id */
- Cc_ChannelActiveA = 3, /* Channel A is currently active */
- Cc_InvalidInputPortA = 4, /* invalid Input A Port */
- Cc_InvalidInputSlotA = 5, /* invalid Input A Slot */
- Cc_BusyInputSlotA = 6, /* busy Input A Slot */
- Cc_InvalidOutputPortA = 7, /* invalid Output A Port */
- Cc_InvalidOutputSlotA = 8, /* invalid Output A Slot */
- Cc_BusyOutputSlotA = 9, /* busy Output A Slot */
- Cc_InvalidInputPortB = 10, /* invalid Input B Port */
- Cc_InvalidInputSlotB = 11, /* invalid Input B Slot */
- Cc_BusyInputSlotB = 12, /* busy Input B Slot */
- Cc_InvalidPktInCodingA = 13, /* invalid Packet In A Coding */
- Cc_InvalidPktOutCodingA = 14, /* invalid Packet Out A Coding */
- Cc_InvalidPktInSizeA = 15, /* invalid Packet In A Frame Size */
- Cc_InvalidPktOutSizeA = 16, /* invalid Packet Out A Frame Size */
-
- Cc_ChanTypeNotConfigured = 21, /* channel type was not configured */
- Cc_InsuffECResources = 22, /* insufficient ecan resources avail. */
- Cc_InsuffTDMResources = 23, /* insufficient tdm block resources avail. */
-
- Cc_InsuffPktBufResources = 25, /* insufficient pkt buffer resources avail. */
- Cc_InsuffPcmBufResources = 26, /* insufficient pcm buffer resources avail. */
-
- Cc_BadPcmEcNlpType = 30, /* invalid EC Nlp type */
- Cc_BadPcmEcTapLength = 31, /* invalid EC tap length */
- Cc_BadPcmEcDblTalkThresh = 32, /* invalid EC double-talk threshold */
- Cc_BadPcmEcNlpThreshold = 33, /* invalid EC Nlp threshold */
- Cc_BadPcmEcCngThreshold = 34, /* invalid EC Cng threshold */
- Cc_BadPcmEcAdaptLimit = 35, /* invalid EC Adapt Limit */
- Cc_BadPcmEcCrossCorrLim = 36, /* invalid EC Cross Correlation Limit */
- Cc_BadPcmEcNumFirSegs = 37, /* invalid EC Number of FirSegments */
- Cc_BadPcmEcFirSegLen = 38, /* invalid EC Fir Segment Length */
-
- /*Cc_InvalidNumEcsEnabled = 48, */ /* more than 1 Ec enabled on channel */
- Cc_InvalidFrameRate = 49, /* invalid gpak frame rate */
- Cc_InvalidSoftCompand = 50, /* invalid softCompanding type */
-
- Cc_InvalidMuteToneA = 51, /* invalid MuteToneA set, no detector */
- Cc_InvalidMuteToneB = 52, /* invalid MuteToneB set, no detector */
- Cc_InsuffFaxCngDetResources = 53 /* insufficient tdm block resources avail. */
-
-} GPAK_ChannelConfigStat_t;
-
-/* Tear Down Channel reply status codes. */
-typedef enum
-{
- Td_Success = 0, /* channel torn down successfully */
- Td_InvalidChannel = 1, /* invalid Channel Id */
- Td_ChannelNotActive = 2 /* channel is not active */
-} GPAK_TearDownChanStat_t;
-
-
-typedef enum
-{
- Ac_Success = 0, /* algorithm control is successfull */
- Ac_InvalidChannel = 1, /* invalid channel identifier */
- Ac_InvalidCode = 2, /* invalid algorithm control code */
- Ac_ECNotEnabled = 3, /* echo canceller was not allocated */
- Ac_InvalidSoftComp = 4, /* invalid softcompanding, 'cause serial port not in companding mode */
- Ac_InvalidDTMFMuteA = 5, /* A side invalid Mute, since no dtmf detector */
- Ac_InvalidDTMFMuteB = 6, /* B side invalid Mute, since no dtmf detector */
- Ac_InvalidFaxCngA = 7, /* A side FAXCNG detector not available */
- Ac_InvalidFaxCngB = 8, /* B side FAXCNG detector not available */
- Ac_InvalidSysConfig = 9 /* No new system parameters (DTMF config) wrriten yet */
-} GPAK_AlgControlStat_t;
-
-/* Write System Parameters reply status codes. */
-typedef enum
-{
- Sp_Success = 0, /* System Parameters written successfully */
- Sp_BadTwistThresh = 29 /* invalid twist threshold */
-
-} GPAK_SysParmsStat_t;
-
-#endif /* prevent multiple inclusion */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/drivers/dahdi/wcte12xp/Kbuild b/drivers/dahdi/wcte12xp/Kbuild
index c462a32..77efd7d 100644
--- a/drivers/dahdi/wcte12xp/Kbuild
+++ b/drivers/dahdi/wcte12xp/Kbuild
@@ -1,18 +1,5 @@
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE12XP) += wcte12xp.o
-FIRM_DIR := ../firmware
-
EXTRA_CFLAGS += -I$(src)/.. -Wno-undef
-ifeq ($(HOTPLUG_FIRMWARE),yes)
- EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
-endif
-
-wcte12xp-objs := base.o vpmadt032.o GpakApi.o voicebus.o
-
-ifneq ($(HOTPLUG_FIRMWARE),yes)
-wcte12xp-objs += $(FIRM_DIR)/dahdi-fw-vpmadt032.o
-endif
-
-$(obj)/$(FIRM_DIR)/dahdi-fw-vpmadt032.o: $(obj)/base.o
- $(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-vpmadt032.o
+wcte12xp-objs := base.o
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index 9294350..30f89e9 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -41,15 +41,13 @@
#include <dahdi/kernel.h>
-#include "../wct4xxp/wct4xxp.h" /* For certain definitions */
+#include "wct4xxp/wct4xxp.h" /* For certain definitions */
-#include "../voicebus.h"
+#include "voicebus/voicebus.h"
#include "wcte12xp.h"
-#if defined(VPM_SUPPORT)
-#include "vpmadt032.h"
-#include "GpakApi.h"
-#endif
+#include "voicebus/GpakCust.h"
+#include "voicebus/GpakApi.h"
struct pci_driver te12xp_driver;
@@ -60,14 +58,11 @@ static int loopback = 0;
static int t1e1override = -1;
static int unchannelized = 0;
static int latency = VOICEBUS_DEFAULT_LATENCY;
-#ifdef VPM_SUPPORT
int vpmsupport = 1;
-int vpmdtmfsupport = 0;
static int vpmtsisupport = 0;
-int vpmnlptype = 1;
+int vpmnlptype = 3;
int vpmnlpthresh = 24;
int vpmnlpmaxsupp = 0;
-#endif
struct t1 *ifaces[WC_MAX_IFACES];
spinlock_t ifacelock = SPIN_LOCK_UNLOCKED;
@@ -205,6 +200,329 @@ static inline void cmd_decipher(struct t1 *wc, volatile unsigned char *readchunk
spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
}
+inline void cmd_decipher_vpmadt032(struct t1 *wc, unsigned char *readchunk)
+{
+ unsigned long flags;
+ struct vpmadt032 *vpm = wc->vpmadt032;
+ struct vpmadt032_cmd *cmd;
+
+ BUG_ON(!vpm);
+
+ /* If the hardware is not processing any commands currently, then
+ * there is nothing for us to do here. */
+ if (list_empty(&vpm->active_cmds)) {
+ return;
+ }
+
+ spin_lock_irqsave(&vpm->list_lock, flags);
+ cmd = list_entry(vpm->active_cmds.next, struct vpmadt032_cmd, node);
+ if (wc->rxident == cmd->txident) {
+ list_del_init(&cmd->node);
+ } else {
+ cmd = NULL;
+ }
+ spin_unlock_irqrestore(&vpm->list_lock, flags);
+
+ if (!cmd) {
+ return;
+ }
+
+ /* Skip audio */
+ readchunk += 66;
+
+ /* Store result */
+ cmd->data = (0xff & readchunk[CMD_BYTE(2, 1, 1)]) << 8;
+ cmd->data |= readchunk[CMD_BYTE(2, 2, 1)];
+ if (cmd->desc & __VPM150M_WR) {
+ /* Writes do not need any acknowledgement */
+ list_add_tail(&cmd->node, &vpm->free_cmds);
+ } else {
+ cmd->desc |= __VPM150M_FIN;
+ complete(&cmd->complete);
+ }
+}
+
+static int config_vpmadt032(struct vpmadt032 *vpm)
+{
+ int res, channel;
+ GpakPortConfig_t portconfig = {0};
+ gpakConfigPortStatus_t configportstatus;
+ GPAK_PortConfigStat_t pstatus;
+ GpakChannelConfig_t chanconfig;
+ GPAK_ChannelConfigStat_t cstatus;
+ GPAK_AlgControlStat_t algstatus;
+
+ /* 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(vpm->dspid, &portconfig, &pstatus))) {
+ printk(KERN_NOTICE "Configuration of ports failed (%d)!\n", configportstatus);
+ return -1;
+ } else {
+ if (vpm->options.debug & DEBUG_ECHOCAN)
+ printk(KERN_DEBUG "Configured McBSP ports successfully\n");
+ }
+
+ if ((res = gpakPingDsp(vpm->dspid, &vpm->version))) {
+ printk(KERN_NOTICE "Error pinging DSP (%d)\n", res);
+ return -1;
+ }
+
+ for (channel = 0; channel < MAX_CHANNELS_PER_SPAN; ++channel) {
+ vpm->curecstate[channel].tap_length = 0;
+ vpm->curecstate[channel].nlp_type = vpm->options.vpmnlptype;
+ vpm->curecstate[channel].nlp_threshold = vpm->options.vpmnlpthresh;
+ vpm->curecstate[channel].nlp_max_suppress = vpm->options.vpmnlpmaxsupp;
+ memcpy(&vpm->desiredecstate[channel], &vpm->curecstate[channel], sizeof(vpm->curecstate[channel]));
+
+ vpm->setchanconfig_from_state(vpm, channel, &chanconfig);
+ if ((res = gpakConfigureChannel(vpm->dspid, channel, tdmToTdm, &chanconfig, &cstatus))) {
+ printk(KERN_NOTICE "Unable to configure channel #%d (%d)", channel, res);
+ if (res == 1) {
+ printk(", reason %d", cstatus);
+ }
+ printk("\n");
+ return -1;
+ }
+
+ if ((res = gpakAlgControl(vpm->dspid, channel, BypassEcanA, &algstatus))) {
+ printk(KERN_NOTICE "Unable to disable echo can on channel %d (reason %d:%d)\n", channel + 1, res, algstatus);
+ return -1;
+ }
+ }
+
+ if ((res = gpakPingDsp(vpm->dspid, &vpm->version))) {
+ printk(KERN_NOTICE "Error pinging DSP (%d)\n", res);
+ return -1;
+ }
+
+ set_bit(VPM150M_ACTIVE, &vpm->control);
+
+ return 0;
+}
+
+static void cmd_dequeue_vpmadt032(struct t1 *wc, unsigned char *writechunk, int whichframe)
+{
+ struct vpmadt032_cmd *cmd;
+ struct vpmadt032 *vpm = wc->vpmadt032;
+ int x;
+ unsigned char leds = ~((atomic_read(&wc->txints) / 1000) % 8) & 0x7;
+
+ /* Skip audio */
+ writechunk += 66;
+
+ if (test_bit(VPM150M_SPIRESET, &vpm->control) || test_bit(VPM150M_HPIRESET, &vpm->control)) {
+ debug_printk(1, "HW Resetting VPMADT032 ...\n");
+ for (x = 0; x < 4; x++) {
+ if (!x) {
+ if (test_and_clear_bit(VPM150M_SPIRESET, &vpm->control))
+ writechunk[CMD_BYTE(x, 0, 1)] = 0x08;
+ else if (test_and_clear_bit(VPM150M_HPIRESET, &vpm->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;
+ }
+
+ if ((cmd = vpmadt032_get_ready_cmd(vpm))) {
+ cmd->txident = wc->txident;
+#if 0
+ printk(KERN_DEBUG "Found command txident = %d, desc = 0x%x, addr = 0x%x, data = 0x%x\n", cmd->txident, cmd->desc, cmd->address, cmd->data);
+#endif
+ if (cmd->desc & __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 (cmd->desc & __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 (cmd->desc & __VPM150M_WR) {
+ writechunk[CMD_BYTE(1, 2, 1)] = cmd->data & 0xf;
+ } else {
+ writechunk[CMD_BYTE(1, 2, 1)] = 0;
+ }
+
+ if (cmd->desc & __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)] = (cmd->address >> 8) & 0xff;
+ writechunk[CMD_BYTE(0, 2, 1)] = cmd->address & 0xff;
+
+ /* Send/Get our data */
+ if (cmd->desc & __VPM150M_WR) {
+ writechunk[CMD_BYTE(1, 0, 1)] = ((0x8 | (0x3 << 1)) << 4);
+ } else {
+ writechunk[CMD_BYTE(1, 0, 1)] = ((0x8 | (0x3 << 1) | 0x1) << 4);
+ }
+ writechunk[CMD_BYTE(1, 1, 1)] = (cmd->data >> 8) & 0xff;
+ writechunk[CMD_BYTE(1, 2, 1)] = cmd->data & 0xff;
+
+ if (cmd->desc & __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)] = (cmd->data >> 8) & 0xff;
+ writechunk[CMD_BYTE(2, 2, 1)] = cmd->data & 0xff;
+ }
+
+ /* 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;
+
+ /* 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, &vpm->control)) {
+ debug_printk(1, "Booting VPMADT032\n");
+ for (x = 0; x < 7; x++) {
+ if (0 == x) {
+ writechunk[CMD_BYTE(x, 0, 1)] = (0x8 << 4);
+ } else {
+ writechunk[CMD_BYTE(x, 0, 1)] = 0x00;
+ }
+ writechunk[CMD_BYTE(x, 1, 1)] = 0;
+ if (0 == x) {
+ 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, &vpm->control) && !whichframe && !(atomic_read(&wc->txints) % 100))
+ schedule_work(&vpm->work);
+
+#if 0
+ /* This may be needed sometime in the future to troubleshoot ADT related issues. */
+ if (test_bit(VPM150M_ACTIVE, &vpm->control) && !whichframe && !(atomic_read(&wc->txints) % 10000))
+ queue_work(vpm->wq, &vpm->work_debug);
+#endif
+}
+
static inline int t1_setreg_full(struct t1 *wc, int addr, int val, int vpm_num)
{
struct command *cmd;
@@ -817,9 +1135,6 @@ static int t1xxp_close(struct dahdi_chan *chan)
static int t1xxp_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
{
- unsigned int x;
- struct t1 *wc = chan->pvt;
-
switch (cmd) {
case WCT4_GET_REGS:
/* Since all register access was moved into the voicebus
@@ -829,78 +1144,22 @@ static int t1xxp_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
WARN_ON(1);
return -ENOSYS;
break;
-#ifdef VPM_SUPPORT
- case DAHDI_TONEDETECT:
- if (get_user(x, (__user int *) data))
- return -EFAULT;
- if (!wc->vpm150m)
- return -ENOSYS;
- if (wc->vpm150m && (x && !vpmdtmfsupport))
- return -ENOSYS;
- if (x & DAHDI_TONEDETECT_ON) {
- set_bit(chan->chanpos - 1, &wc->dtmfmask);
- module_printk("turning on tone detection\n");
- } else {
- clear_bit(chan->chanpos - 1, &wc->dtmfmask);
- module_printk("turning off tone detection\n");
- }
- if (x & DAHDI_TONEDETECT_MUTE) {
- if(wc->vpm150m)
- set_bit(chan->chanpos - 1, &wc->vpm150m->desireddtmfmutestate);
- } else {
- if(wc->vpm150m)
- clear_bit(chan->chanpos - 1, &wc->vpm150m->desireddtmfmutestate);
- }
- return 0;
-#endif
default:
return -ENOTTY;
}
return 0;
}
-#ifdef VPM_SUPPORT
-
-#include "adt_lec.c"
-
-static int t1xxp_echocan_with_params(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
+static int t1xxp_echocan_with_params(struct dahdi_chan *chan,
+ struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
{
- struct adt_lec_params params;
struct t1 *wc = chan->pvt;
- struct vpm150m *vpm150m = wc->vpm150m;
- unsigned long flags;
- struct vpm150m_workentry *work;
- unsigned int ret;
-
- if (!wc->vpm150m)
+ if (!wc->vpmadt032) {
return -ENODEV;
-
- adt_lec_init_defaults(&params, 32);
-
- if ((ret = adt_lec_parse_params(&params, ecp, p)))
- return ret;
-
- /* we can't really control the tap length, but the value is used
- to control whether the ec is on or off, so translate it */
- params.tap_length = ecp->tap_length ? 1 : 0;
-
- if (!(work = kmalloc(sizeof(*work), GFP_KERNEL)))
- return -ENOMEM;
-
- work->params = params;
- work->wc = wc;
- work->chan = chan;
- spin_lock_irqsave(&vpm150m->lock, flags);
- list_add_tail(&work->list, &vpm150m->worklist);
- spin_unlock_irqrestore(&vpm150m->lock, flags);
-
- /* we must do this later since we cannot sleep in the echocan function */
- if (test_bit(VPM150M_ACTIVE, &vpm150m->control))
- queue_work(vpm150m->wq, &vpm150m->work_echocan);
-
- return 0; /* how do I return the status since it is done later by the workqueue? */
+ }
+ return vpmadt032_echocan_with_params(wc->vpmadt032, chan->chanpos - 1,
+ ecp, p);
}
-#endif
static int t1_software_init(struct t1 *wc)
{
@@ -930,7 +1189,7 @@ static int t1_software_init(struct t1 *wc)
strncpy(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype) - 1);
#if defined(VPM_SUPPORT)
- if (wc->vpm150m)
+ if (wc->vpmadt032)
strncat(wc->span.devicetype, " with VPMADT032", sizeof(wc->span.devicetype) - 1);
#endif
@@ -1001,9 +1260,64 @@ static inline unsigned char t1_vpm_out(struct t1 *wc, int unit, const unsigned i
#endif
+static void setchanconfig_from_state(struct vpmadt032 *vpm, int channel, GpakChannelConfig_t *chanconfig)
+{
+ const struct vpmadt032_options *options;
+
+ BUG_ON(!vpm);
+
+ options = &vpm->options;
+
+ chanconfig->PcmInPortA = 3;
+ chanconfig->PcmInSlotA = (channel + 1) * 2;
+ chanconfig->PcmOutPortA = 2;
+ chanconfig->PcmOutSlotA = (channel + 1) * 2;
+ chanconfig->PcmInPortB = 2;
+ chanconfig->PcmInSlotB = (channel + 1) * 2;
+ chanconfig->PcmOutPortB = 3;
+ chanconfig->PcmOutSlotB = (channel + 1) * 2;
+ 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 = cmpPCMU;
+
+ chanconfig->FrameRate = rate10ms;
+ chanconfig->EcanParametersA.EcanTapLength = 1024;
+ chanconfig->EcanParametersA.EcanNlpType = vpm->curecstate[channel].nlp_type;
+ chanconfig->EcanParametersA.EcanAdaptEnable = 1;
+ chanconfig->EcanParametersA.EcanG165DetEnable = 1;
+ chanconfig->EcanParametersA.EcanDblTalkThresh = 6;
+ chanconfig->EcanParametersA.EcanMaxDoubleTalkThres = 40;
+ chanconfig->EcanParametersA.EcanNlpThreshold = vpm->curecstate[channel].nlp_threshold;
+ chanconfig->EcanParametersA.EcanNlpConv = 0;
+ chanconfig->EcanParametersA.EcanNlpUnConv = 12;
+ chanconfig->EcanParametersA.EcanNlpMaxSuppress = vpm->curecstate[channel].nlp_max_suppress;
+ chanconfig->EcanParametersA.EcanCngThreshold = 43;
+ chanconfig->EcanParametersA.EcanAdaptLimit = 50;
+ chanconfig->EcanParametersA.EcanCrossCorrLimit = 15;
+ chanconfig->EcanParametersA.EcanNumFirSegments = 3;
+ chanconfig->EcanParametersA.EcanFirSegmentLen = 48;
+ chanconfig->EcanParametersA.EcanReconvergenceCheckEnable = 1;
+ chanconfig->EcanParametersA.EcanTandemOperationEnable = 1;
+ chanconfig->EcanParametersA.EcanMixedFourWireMode = 1;
+
+
+ memcpy(&chanconfig->EcanParametersB,
+ &chanconfig->EcanParametersA,
+ sizeof(chanconfig->EcanParametersB));
+}
+
static int t1_hardware_post_init(struct t1 *wc)
{
+ struct vpmadt032_options options;
unsigned int reg;
+ int res;
int x;
/* T1 or E1 */
@@ -1036,17 +1350,41 @@ static int t1_hardware_post_init(struct t1 *wc)
t1_setleds(wc, wc->ledstate);
#ifdef VPM_SUPPORT
- t1_vpm150m_init(wc);
- if (wc->vpm150m) {
- module_printk("VPM present and operational (Firmware version %x)\n", wc->vpm150m->version);
- set_bit(4, &wc->ctlreg); /* turn on vpm (RX audio from vpm module) */
+ if (vpmsupport) {
+ memset(&options, 0, sizeof(options));
+ options.debug = debug;
+ options.vpmnlptype = vpmnlptype;
+ options.vpmnlpthresh = vpmnlpthresh;
+ options.vpmnlpmaxsupp = vpmnlpmaxsupp;
+
+ wc->vpmadt032 = vpmadt032_alloc(&options);
+ if (!wc->vpmadt032)
+ return -ENOMEM;
+
+ wc->vpmadt032->context = wc;
+ wc->vpmadt032->setchanconfig_from_state = setchanconfig_from_state;
+ wc->vpmadt032->span = &wc->span;
+
+ res = vpmadt032_init(wc->vpmadt032, wc->vb);
+ if (res) {
+ vpmadt032_free(wc->vpmadt032);
+ wc->vpmadt032=NULL;
+ return -EIO;
+ }
+
+ config_vpmadt032(wc->vpmadt032);
+
+ module_printk("VPM present and operational (Firmware version %x)\n", wc->vpmadt032->version);
+ wc->ctlreg |= 0x10; /* turn on vpm (RX audio from vpm module) */
if (vpmtsisupport) {
debug_printk(1, "enabling VPM TSI pin\n");
- set_bit(0, &wc->ctlreg); /* turn on vpm timeslot interchange pin */
+ wc->ctlreg |= 0x01; /* turn on vpm timeslot interchange pin */
}
+ } else {
+ module_printk("VPM Support Disabled\n");
+ wc->vpmadt032 = NULL;
}
#endif
-
return 0;
}
@@ -1234,9 +1572,9 @@ static inline void t1_transmitprep(struct t1 *wc, unsigned char* writechunk)
cmd_dequeue(wc, writechunk, x, y);
}
#ifdef VPM_SUPPORT
- if(likely(wc->vpm150m)) {
+ if(likely(wc->vpmadt032)) {
spin_lock(&wc->reglock);
- vpm150m_cmd_dequeue(wc, writechunk, x);
+ cmd_dequeue_vpmadt032(wc, writechunk, x);
spin_unlock(&wc->reglock);
}
#endif
@@ -1273,9 +1611,9 @@ static inline void t1_receiveprep(struct t1 *wc, unsigned char* readchunk)
}
cmd_decipher(wc, readchunk);
#ifdef VPM_SUPPORT
- if (wc->vpm150m) {
+ if (wc->vpmadt032) {
spin_lock(&wc->reglock);
- vpm150m_cmd_decipher(wc, readchunk);
+ cmd_decipher_vpmadt032(wc, readchunk);
spin_unlock(&wc->reglock);
}
#endif
@@ -1445,17 +1783,16 @@ static void __devexit te12xp_remove_one(struct pci_dev *pdev)
struct t1 *wc = pci_get_drvdata(pdev);
#ifdef VPM_SUPPORT
unsigned long flags;
- struct vpm150m *vpm150m = wc->vpm150m;
+ struct vpmadt032 *vpm = wc->vpmadt032;
#endif
if (!wc)
return;
#ifdef VPM_SUPPORT
- if(vpm150m) {
- clear_bit(VPM150M_DTMFDETECT, &vpm150m->control);
- clear_bit(VPM150M_ACTIVE, &vpm150m->control);
- flush_workqueue(vpm150m->wq);
- destroy_workqueue(vpm150m->wq);
+ if(vpm) {
+ wc->vpmadt032 = NULL;
+ clear_bit(VPM150M_DTMFDETECT, &vpm->control);
+ clear_bit(VPM150M_ACTIVE, &vpm->control);
}
#endif
clear_bit(INITIALIZED, &wc->bit_flags);
@@ -1468,12 +1805,10 @@ static void __devexit te12xp_remove_one(struct pci_dev *pdev)
wc->vb = NULL;
#ifdef VPM_SUPPORT
- if(vpm150m) {
+ if(vpm) {
spin_lock_irqsave(&wc->reglock, flags);
- wc->vpm150m = NULL;
- vpm150m->wc = NULL;
spin_unlock_irqrestore(&wc->reglock, flags);
- kfree(wc->vpm150m);
+ vpmadt032_free(vpm);
}
#endif
t1_release(wc);
@@ -1537,7 +1872,6 @@ module_param(alarmdebounce, int, S_IRUGO | S_IWUSR);
module_param(latency, int, S_IRUGO | S_IWUSR);
#ifdef VPM_SUPPORT
module_param(vpmsupport, int, S_IRUGO | S_IWUSR);
-module_param(vpmdtmfsupport, int, S_IRUGO | S_IWUSR);
module_param(vpmtsisupport, int, S_IRUGO | S_IWUSR);
#endif
diff --git a/drivers/dahdi/wcte12xp/gpakenum.h b/drivers/dahdi/wcte12xp/gpakenum.h
deleted file mode 100644
index c2a5175..0000000
--- a/drivers/dahdi/wcte12xp/gpakenum.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2005, Adaptive Digital Technologies, Inc.
- *
- * File Name: gpakenum.h
- *
- * Description:
- * This file contains common enumerations related to G.PAK application
- * software.
- *
- * Version: 1.0
- *
- * Revision History:
- * 06/15/05 - Initial release.
- *
- * This program has been released under the terms of the GPL version 2 by
- * permission of Adaptive Digital Technologies, Inc.
- *
- */
-
-/*
- * 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.
- */
-
-#ifndef _GPAKENUM_H /* prevent multiple inclusion */
-#define _GPAKENUM_H
-
-/* G.PAK Serial Port Word Size */
-typedef enum
-{
- SerWordSize8 = 0, // 8-bit seial word
- SerWordSize16 = 1 // 16-bit serial word
-} GpakSerWordSize_t;
-
-/* G.PAK Serial Port FrameSync Polarity */
-typedef enum
-{
- FrameSyncActLow = 0, // active low frame sync signal
- FrameSyncActHigh = 1 // active high frame sync signal
-} GpakSerFrameSyncPol_t;
-
-/* G.PAK Serial Port Clock Polarity */
-typedef enum
-{
- SerClockActLow = 0, // active low serial clock
- SerClockActHigh = 1 // active high serial clock
-} GpakSerClockPol_t;
-
-/* G.PAK Serial Port Data Delay */
-typedef enum
-{
- DataDelay0 = 0, // no data delay
- DataDelay1 = 1, // 1-bit data delay
- DataDelay2 = 2 // 2-bit data delay
-} GpakSerDataDelay_t;
-
-/* G.PAK Serial Port Ids. */
-typedef enum
-{
- SerialPortNull = 0, // null serial port
- SerialPort1 = 1, // first PCM serial stream port (McBSP0)
- SerialPort2 = 2, // second PCM serial stream port (McBSP1)
- SerialPort3 = 3 // third PCM serial stream port (McBSP2)
-} GpakSerialPort_t;
-
-/* G.PAK serial port Slot Configuration selection codes. */
-typedef enum
-{
- SlotCfgNone = 0, // no time slots used
- SlotCfg2Groups = 2, // 2 groups of 16 time slots used, 32 Channels system
- SlotCfg8Groups = 8 // 8-partition mode for 128-channel system
-} GpakSlotCfg_t;
-
-/* G.PAK serial port Companding Mode codes. */
-typedef enum
-{
- cmpPCMU=0, // u-Law
- cmpPCMA=1, // A-Law
- cmpNone=2 // none
-} GpakCompandModes;
-
-/* G.PAK Active/Inactive selection codes. */
-typedef enum
-{
- Disabled=0, // Inactive
- Enabled=1 // Active
-} GpakActivation;
-
-/* G.PAK Channel Type codes. */
-typedef enum
-{
- inactive=0, // channel inactive
- tdmToTdm=1 // tdmToTdm
-} GpakChanType;
-
-/* G.PAK Algorithm control commands */
-typedef enum
-{
- EnableEcanA = 0, // Enable A side echo canceller
- BypassEcanA = 1, // Bypass A side echo canceller
- ResetEcanA = 2, // Reset A side echo canceller
- EnableEcanB = 3, // Enable B side echo canceller
- BypassEcanB = 4, // Bypass B side echo canceller
- ResetEcanB = 5, // Reset B side echo canceller
-
- EnableMuLawSwCompanding = 6,// Enable Mu-law Software companding
- EnableALawSwCompanding = 7, // Enable Mu-law Software companding
- BypassSwCompanding = 8, // Bypass Software companding
- EnableDTMFMuteA = 9, // Mute A side Dtmf digit after tone detected
- DisableDTMFMuteA = 10, // Do not mute A side Dtmf digit once tone detected
- EnableDTMFMuteB = 11, // Mute B side Dtmf digit after tone detected
- DisableDTMFMuteB = 12, // Do not mute B side Dtmf digit once tone detected
- EnableFaxCngDetectA = 13, // Enable A side Fax CNG detector, channel must be configed already
- DisableFaxCngDetectA = 14, // Disable A side Fax CNG detector, channel must be configed already
- EnableFaxCngDetectB = 15, // Enable B side Fax CNG detector, channel must be configed already
- DisableFaxCngDetectB = 16 // Disable B side Fax CNG detector, channel must be configed already
-} GpakAlgCtrl_t;
-
-/* G.PAK Tone types. */
-typedef enum
-{
- Null_tone = 0, // no tone detection
- DTMF_tone = 1 // DTMF tone
-} GpakToneTypes;
-
-/* G.PAK direction. */
-typedef enum
-{
- TDMAToB = 0, // A to B
- TDMBToA = 1 // B to A
-} GpakTdmDirection;
-
-
-typedef enum
-{
- rate1ms=0,
- rate2ms=1,
- rate10ms=2
-} GpakRate_t;
-
-/* G.PAK Asynchronous Event Codes */
-typedef enum
-{
- EventToneDetect = 0, // Tone detection event
- EventDSPDebug = 7 // DSP debug data event
-} GpakAsyncEventCode_t;
-
-/* G.PAK MF Tone Code Indices */
-typedef enum
-{
- DtmfDigit1 = 0, // DTMF Digit 1
- DtmfDigit2 = 1, // DTMF Digit 2
- DtmfDigit3 = 2, // DTMF Digit 3
- DtmfDigitA = 3, // DTMF Digit A
- DtmfDigit4 = 4, // DTMF Digit 4
- DtmfDigit5 = 5, // DTMF Digit 5
- DtmfDigit6 = 6, // DTMF Digit 6
- DtmfDigitB = 7, // DTMF Digit B
- DtmfDigit7 = 8, // DTMF Digit 7
- DtmfDigit8 = 9, // DTMF Digit 8
- DtmfDigit9 = 10, // DTMF Digit 9
- DtmfDigitC = 11, // DTMF Digit C
- DtmfDigitSt = 12, // DTMF Digit *
- DtmfDigit0 = 13, // DTMF Digit 0
- DtmfDigitPnd = 14, // DTMF Digit #
- DtmfDigitD = 15, // DTMF Digit D
-
- FaxCngDigit = 90, // Fax Calling Tone (1100 Hz)
-
- EndofMFDigit = 100, // End of MF digit
- EndofCngDigit = 101 // End of Cng Digit
-} GpakToneCodes_t;
-
-/* GPIO control code*/
-typedef enum
-{
- GPIO_READ = 0,
- GPIO_WRITE = 1,
- GPIO_DIR = 2
-} GpakGPIOCotrol_t;
-
-#endif // end multiple inclusion
diff --git a/drivers/dahdi/wcte12xp/voicebus.c b/drivers/dahdi/wcte12xp/voicebus.c
deleted file mode 120000
index 6653619..0000000
--- a/drivers/dahdi/wcte12xp/voicebus.c
+++ /dev/null
@@ -1 +0,0 @@
-../voicebus.c \ No newline at end of file
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, &reg);
- 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
diff --git a/drivers/dahdi/wcte12xp/vpmadt032.h b/drivers/dahdi/wcte12xp/vpmadt032.h
deleted file mode 100644
index da50d6a..0000000
--- a/drivers/dahdi/wcte12xp/vpmadt032.h
+++ /dev/null
@@ -1,151 +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.
- */
-
-#ifndef _VPM150M_H
-#define _VPM150M_H
-
-#include "wcte12xp.h"
-#include "adt_lec.h"
-
-struct t1_firmware {
- const struct firmware *fw;
- unsigned int offset;
-};
-
-/* Host and DSP system dependent related definitions. */
-#define MAX_DSP_CORES 128 /* maximum number of DSP cores */
-//#define MAX_CONFS 1 /* maximum number of conferences */
-//#define MAX_PKT_CHANNELS 8 /* maximum number of packet channels */
-#define MAX_CHANNELS 32 /* maximum number of channels */
-#define MAX_WAIT_LOOPS 50 /* max number of wait delay loops */
-#define DSP_IFBLK_ADDRESS 0x0100 /* DSP address of I/F block pointer */
-#define DOWNLOAD_BLOCK_SIZE 512 /* download block size (DSP words) */
-//#define MAX_CIDPAYLOAD_BYTES 512 /* max size of a CID payload (octets) */
-typedef unsigned short DSP_WORD; /* 16 bit DSP word */
-typedef unsigned int DSP_ADDRESS; /* 32 bit DSP address */
-typedef struct t1_firmware* GPAK_FILE_ID; /* G.PAK Download file identifier */
-
-#define __VPM150M_RWPAGE (1 << 4)
-#define __VPM150M_RD (1 << 3)
-#define __VPM150M_WR (1 << 2)
-#define __VPM150M_FIN (1 << 1)
-#define __VPM150M_TX (1 << 0)
-
-#define VPM150M_HPI_CONTROL 0x00
-#define VPM150M_HPI_ADDRESS 0x02
-#define VPM150M_HPI_DATA 0x03
-
-#define VPM150M_MAX_COMMANDS 8
-
-/* Some Bit ops for different operations */
-#define VPM150M_SPIRESET 0
-#define VPM150M_HPIRESET 1
-#define VPM150M_SWRESET 2
-#define VPM150M_DTMFDETECT 3
-#define VPM150M_ACTIVE 4
-#define VPM150M_MAX_DATA 1
-
-struct vpm150m_cmd {
- unsigned short address;
- unsigned short data[VPM150M_MAX_DATA];
- unsigned char ident;
- unsigned char datalen;
- unsigned int flags;
- unsigned char cs_slot;
-};
-
-struct vpm150m {
- unsigned short dspid;
- unsigned long control;
- unsigned char curpage;
- unsigned short version;
- struct vpm150m_cmd cmdq[VPM150M_MAX_COMMANDS];
- spinlock_t lock; /* control access to list of bottom half tasks */
- struct semaphore sem;
- struct workqueue_struct *wq;
- struct work_struct work_dtmf;
- struct work_struct work_debug;
- struct work_struct work_echocan;
- struct list_head worklist;
- unsigned char curtone[32];
- unsigned long curdtmfmutestate;
- unsigned long desireddtmfmutestate;
- struct adt_lec_params chan_params[32];
- struct t1 *wc;
-};
-
-/* linked list for vpm echocan workqueue*/
-struct vpm150m_workentry {
- struct list_head list;
- struct t1 *wc; /* what card are we dealing with? */
- struct dahdi_chan *chan; /* what channels are we going to deal with? */
- struct adt_lec_params params; /* how should we behave? */
-};
-
-extern int debug;
-extern int vpmsupport;
-extern int vpmdtmfsupport;
-extern struct pci_driver te12xp_driver;
-extern struct t1 *ifaces[WC_MAX_IFACES];
-extern int vpmnlptype;
-extern int vpmnlpthresh;
-extern int vpmnlpmaxsupp;
-
-void t1_vpm150m_init(struct t1 *wc);
-void vpm150m_cmd_dequeue(struct t1 *wc, volatile unsigned char *writechunk, int whichframe);
-void vpm150m_cmd_decipher(struct t1 *wc, volatile unsigned char *readchunk);
-int vpm150m_config_hw(struct t1 *wc);
-
-/* gpak API functions */
-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 */
- );
-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 */
- );
-void gpakHostDelay(void);
-void gpakLockAccess(
- unsigned short int DspId /* DSP Identifier (0 to MAX_DSP_CORES-1) */
- );
-void gpakUnlockAccess(
- unsigned short int DspId /* DSP Identifier (0 to MAX_DSP_CORES-1) */
- );
-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 */
- );
-
-#endif
diff --git a/drivers/dahdi/wcte12xp/wcte12xp.h b/drivers/dahdi/wcte12xp/wcte12xp.h
index 655ac30..a93df54 100644
--- a/drivers/dahdi/wcte12xp/wcte12xp.h
+++ b/drivers/dahdi/wcte12xp/wcte12xp.h
@@ -8,7 +8,7 @@
* Matthew Fredrickson <creslin@digium.com>
* William Meadows <wmeadows@digium.com>
*
- * Copyright (C) 2007, Digium, Inc.
+ * Copyright (C) 2007-2009, Digium, Inc.
*
* All rights reserved.
*
@@ -130,13 +130,11 @@ struct t1 {
unsigned long ctlreg;
struct voicebus* vb;
atomic_t txints;
-#ifdef VPM_SUPPORT
- int vpm;
- struct vpm150m *vpm150m;
+ int vpm100;
+ struct vpmadt032 *vpmadt032;
unsigned long dtmfactive;
unsigned long dtmfmask;
unsigned long dtmfmutemask;
-#endif
spinlock_t cmd_list_lock;
struct list_head pending_cmds;