summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2009-04-29 17:48:39 +0000
committerShaun Ruffell <sruffell@digium.com>2009-04-29 17:48:39 +0000
commit0eab8786edae3a7cc06d9f37793aefb712358cd3 (patch)
tree7feb878aab3e215b5c2011374fb84b68326a55bd
parent1b2c87acf7f48bb85c155a026ef20a8f0be21c57 (diff)
voicebus: Move common vpmadt032 interface into voicebus module.
The voicebus library was previously linked into both the wcte12xp and wctdm24xxp drivers. It is now broken out into it's own module and the common parts of the vpmadt032 interface are now located in that module to reduce duplication between the wcte12xp and wctdm24xxp drivers. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@6527 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-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;