wct4xxp, wcte13xp: Move the octasic DSP code into separate module.

The octasic library is relatively large and is currently separately linked into
both the wcte13xp and wct4xxp libraries. This change moves it out into a
separate loadable module.

The bigest change from the drivers perspectives is that they must provide a
table of callbacks instead of using statically linked Oct6100UserXxxxx functions
to allow the library to communicate with actual parts on the cards.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
This commit is contained in:
Shaun Ruffell 2013-06-24 15:22:18 -05:00
parent a648cef0f6
commit 26efcf6902
10 changed files with 372 additions and 194 deletions

View File

@ -82,7 +82,7 @@ include/dahdi/version.h: FORCE
fi
@rm -f $@.tmp
prereq: include/dahdi/version.h firmware-loaders oct612x-lib
prereq: include/dahdi/version.h firmware-loaders
stackcheck: $(CHECKSTACK) modules
objdump -d drivers/dahdi/*.ko drivers/dahdi/*/*.ko | $(CHECKSTACK)
@ -118,13 +118,6 @@ uninstall-firmware:
firmware-loaders:
$(MAKE) -C drivers/dahdi/firmware firmware-loaders
oct612x-lib:
ifeq (no,$(HAS_KSRC))
@echo "You do not appear to have the sources for the $(KVERS) kernel installed."
@exit 1
endif
$(MAKE) -C $(KSRC) M='$(PWD)/drivers/dahdi/oct612x'
install-include:
for hdr in $(INST_HEADERS); do \
install -D -m 644 include/dahdi/$$hdr $(DESTDIR)/usr/include/dahdi/$$hdr; \

View File

@ -7,14 +7,15 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETHMF) += dahdi_dynamic_ethmf.o
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TRANSCODE) += dahdi_transcode.o
ifdef CONFIG_PCI
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OCT612X) += oct612x/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP) += wct4xxp/
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_WCTE13XP) += wcte13xp.o
wcte13xp-objs := wcte13xp-base.o oct612x/lib.a
CFLAGS_wcte13xp-base.o += -I$(src)/oct612x/include -I$(src)/oct612x/octdeviceapi -I$(src)/oct612x/octdeviceapi/oct6100api
wcte13xp-objs := wcte13xp-base.o
CFLAGS_wcte13xp-base.o += -I$(src)/oct612x -I$(src)/oct612x/include -I$(src)/oct612x/octdeviceapi -I$(src)/oct612x/octdeviceapi/oct6100api
ifeq ($(HOTPLUG_FIRMWARE),yes)
CFLAGS_wcte13xp-base.o += -DHOTPLUG_FIRMWARE
endif

View File

@ -0,0 +1,32 @@
#
# Produces the oct612x library
#
octapi_files = octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_channel.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_debug.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_events.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_memory.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.o \
apilib/bt/octapi_bt0.o \
apilib/largmath/octapi_largmath.o \
apilib/llman/octapi_llman.o \
oct612x-user.o
# TODO: ccflags was added in 2.6.24 in commit f77bf01425b11947eeb3b5b54. This
# should be changed to a conditional compilation based on the Kernel Version.
# ccflags-y := -I$(src)/.. -Wno-undef -I$(src)/include -I$(src)/octdeviceapi -I$(src)/octdeviceapi/oct6100api
EXTRA_CFLAGS = -I$(src)/.. -Wno-undef -I$(src)/include -I$(src)/octdeviceapi -I$(src)/octdeviceapi/oct6100api
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OCT612X) := oct612x.o
oct612x-objs := $(octapi_files)

View File

@ -0,0 +1,181 @@
/*
* Octasic OCT6100 Interface
*
* Copyright (C) 2013 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/kernel.h>
#include <linux/module.h>
#include "oct612x.h"
UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
{
/* Why couldn't they just take a timeval like everyone else? */
struct timeval tv;
unsigned long long total_usecs;
unsigned int mask = ~0;
do_gettimeofday(&tv);
total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
(((unsigned long long)(tv.tv_usec)));
f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern,
UINT32 f_ulLength)
{
memset(f_pAddress, f_ulPattern, f_ulLength);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource,
UINT32 f_ulLength)
{
memcpy(f_pDestination, f_pSource, f_ulLength);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserCreateSerializeObject(
tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
{
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDestroySerializeObject(
tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
{
#ifdef OCTASIC_DEBUG
pr_debug("I should never be called! (destroy serialize object)\n");
#endif
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserSeizeSerializeObject(
tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserReleaseSerializeObject(
tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
{
struct oct612x_context *context = f_pWriteParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->write) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->write(context, f_pWriteParams->ulWriteAddress,
f_pWriteParams->usWriteData);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
{
struct oct612x_context *context = f_pSmearParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->write_smear) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->write_smear(context, f_pSmearParams->ulWriteAddress,
f_pSmearParams->usWriteData,
f_pSmearParams->ulWriteLength);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteBurstApi(
tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
{
struct oct612x_context *context = f_pBurstParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->write_burst) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->write_burst(context, f_pBurstParams->ulWriteAddress,
f_pBurstParams->pusWriteData,
f_pBurstParams->ulWriteLength);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
{
struct oct612x_context *context = f_pReadParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->read) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->read(context, f_pReadParams->ulReadAddress,
f_pReadParams->pusReadData);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
{
struct oct612x_context *context = f_pBurstParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->read_burst) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->read_burst(context, f_pBurstParams->ulReadAddress,
f_pBurstParams->pusReadData,
f_pBurstParams->ulReadLength);
return cOCT6100_ERR_OK;
}
EXPORT_SYMBOL(Oct6100ChipOpen);
EXPORT_SYMBOL(Oct6100ChipClose);
EXPORT_SYMBOL(Oct6100ChipCloseDef);
EXPORT_SYMBOL(Oct6100GetInstanceSize);
EXPORT_SYMBOL(Oct6100GetInstanceSizeDef);
EXPORT_SYMBOL(Oct6100ChipOpenDef);
EXPORT_SYMBOL(Oct6100ChannelModify);
EXPORT_SYMBOL(Oct6100ToneDetectionEnableDef);
EXPORT_SYMBOL(Oct6100InterruptServiceRoutine);
EXPORT_SYMBOL(Oct6100InterruptServiceRoutineDef);
EXPORT_SYMBOL(Oct6100ApiGetCapacityPins);
EXPORT_SYMBOL(Oct6100ToneDetectionEnable);
EXPORT_SYMBOL(Oct6100EventGetToneDef);
EXPORT_SYMBOL(Oct6100EventGetTone);
EXPORT_SYMBOL(Oct6100ApiGetCapacityPinsDef);
EXPORT_SYMBOL(Oct6100ChannelOpen);
EXPORT_SYMBOL(Oct6100ChannelOpenDef);
EXPORT_SYMBOL(Oct6100ChannelModifyDef);
MODULE_AUTHOR("Digium Incorporated <support@digium.com>");
MODULE_DESCRIPTION("Octasic OCT6100 Hardware Echocan Library");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,49 @@
/*
* Octasic OCT6100 Interface
*
* Copyright (C) 2013 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 __OCT612X_H__
#define __OCT612X_H__
#include <oct6100api/oct6100_api.h>
struct oct612x_context;
/**
* struct oct612x_ops - Callbacks used by oct612x library to talk to part.
*
*/
struct oct612x_ops {
int (*write)(struct oct612x_context *context, u32 address, u16 value);
int (*read)(struct oct612x_context *context, u32 address, u16 *value);
int (*write_smear)(struct oct612x_context *context, u32 address,
u16 value, size_t count);
int (*write_burst)(struct oct612x_context *context, u32 address,
const u16 *value, size_t count);
int (*read_burst)(struct oct612x_context *context, u32 address,
u16 *value, size_t count);
};
struct oct612x_context {
const struct oct612x_ops *ops;
struct device *dev;
};
#endif /* __OCT612X_H__ */

View File

@ -2,7 +2,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP) += wct4xxp.o
FIRM_DIR := ../firmware
EXTRA_CFLAGS += -I$(src)/.. $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
EXTRA_CFLAGS += -I$(src)/.. -I$(src)/../oct612x/ $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
# The OCT612X source files are from a vendor drop and we do not want to edit
# them to make this warning go away. Therefore, turn off the
@ -14,7 +14,7 @@ ifeq ($(HOTPLUG_FIRMWARE),yes)
EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
endif
wct4xxp-objs := base.o vpm450m.o ../oct612x/lib.a
wct4xxp-objs := base.o vpm450m.o
ifneq ($(HOTPLUG_FIRMWARE),yes)
wct4xxp-objs += $(FIRM_DIR)/dahdi-fw-oct6114-064.o $(FIRM_DIR)/dahdi-fw-oct6114-128.o $(FIRM_DIR)/dahdi-fw-oct6114-256.o

View File

@ -4363,7 +4363,7 @@ static void t4_vpm_init(struct t4 *wc)
laws[x] = 1;
}
vpm_capacity = get_vpm450m_capacity(wc);
vpm_capacity = get_vpm450m_capacity(&wc->dev->dev);
if (vpm_capacity != wc->numspans * 32) {
dev_info(&wc->dev->dev, "Disabling VPMOCT%03d. TE%dXXP"\
" requires a VPMOCT%03d", vpm_capacity,
@ -4435,7 +4435,8 @@ static void t4_vpm_init(struct t4 *wc)
return;
}
if (!(wc->vpm = init_vpm450m(wc, laws, wc->numspans, firmware))) {
wc->vpm = init_vpm450m(&wc->dev->dev, laws, wc->numspans, firmware);
if (!wc->vpm) {
dev_notice(&wc->dev->dev, "VPM450: Failed to initialize\n");
if (firmware != &embedded_firmware)
release_firmware(firmware);

View File

@ -31,99 +31,62 @@
#include <stdbool.h>
#include "vpm450m.h"
#include "oct6100api/oct6100_api.h"
#include <oct612x.h>
/* API for Octasic access */
UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
static int wct4xxp_oct612x_write(struct oct612x_context *context,
u32 address, u16 value)
{
/* Why couldn't they just take a timeval like everyone else? */
struct timeval tv;
unsigned long long total_usecs;
unsigned int mask = ~0;
do_gettimeofday(&tv);
total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
(((unsigned long long)(tv.tv_usec)));
f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
return cOCT6100_ERR_OK;
struct t4 *wc = dev_get_drvdata(context->dev);
oct_set_reg(wc, address, value);
return 0;
}
UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength)
static int wct4xxp_oct612x_read(struct oct612x_context *context, u32 address,
u16 *value)
{
memset(f_pAddress, f_ulPattern, f_ulLength);
return cOCT6100_ERR_OK;
struct t4 *wc = dev_get_drvdata(context->dev);
*value = (u16)oct_get_reg(wc, address);
return 0;
}
UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength)
static int wct4xxp_oct612x_write_smear(struct oct612x_context *context,
u32 address, u16 value, size_t count)
{
memcpy(f_pDestination, f_pSource, f_ulLength);
return cOCT6100_ERR_OK;
struct t4 *wc = dev_get_drvdata(context->dev);
int i;
for (i = 0; i < count; ++i)
oct_set_reg(wc, address + (i << 1), value);
return 0;
}
UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
static int wct4xxp_oct612x_write_burst(struct oct612x_context *context,
u32 address, const u16 *buffer,
size_t count)
{
return cOCT6100_ERR_OK;
struct t4 *wc = dev_get_drvdata(context->dev);
int i;
for (i = 0; i < count; ++i)
oct_set_reg(wc, address + (i << 1), buffer[i]);
return 0;
}
UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
static int wct4xxp_oct612x_read_burst(struct oct612x_context *context,
u32 address, u16 *buffer, size_t count)
{
#ifdef OCTASIC_DEBUG
printk(KERN_DEBUG "I should never be called! (destroy serialize object)\n");
#endif
return cOCT6100_ERR_OK;
struct t4 *wc = dev_get_drvdata(context->dev);
int i;
for (i = 0; i < count; ++i)
buffer[i] = oct_get_reg(wc, address + (i << 1));
return 0;
}
UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
{
oct_set_reg(f_pWriteParams->pProcessContext, f_pWriteParams->ulWriteAddress, f_pWriteParams->usWriteData);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
{
unsigned int x;
for (x=0;x<f_pSmearParams->ulWriteLength;x++) {
oct_set_reg(f_pSmearParams->pProcessContext, f_pSmearParams->ulWriteAddress + (x << 1), f_pSmearParams->usWriteData);
}
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
{
unsigned int x;
for (x=0;x<f_pBurstParams->ulWriteLength;x++) {
oct_set_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulWriteAddress + (x << 1), f_pBurstParams->pusWriteData[x]);
}
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
{
*(f_pReadParams->pusReadData) = oct_get_reg(f_pReadParams->pProcessContext, f_pReadParams->ulReadAddress);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
{
unsigned int x;
for (x=0;x<f_pBurstParams->ulReadLength;x++) {
f_pBurstParams->pusReadData[x] = oct_get_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulReadAddress + (x << 1));
}
return cOCT6100_ERR_OK;
}
static const struct oct612x_ops wct4xxp_oct612x_ops = {
.write = wct4xxp_oct612x_write,
.read = wct4xxp_oct612x_read,
.write_smear = wct4xxp_oct612x_write_smear,
.write_burst = wct4xxp_oct612x_write_burst,
.read_burst = wct4xxp_oct612x_read_burst,
};
#define SOUT_G168_1100GB_ON 0x40000004
#define SOUT_DTMF_1 0x40000011
@ -173,6 +136,7 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
struct vpm450m {
tPOCT6100_INSTANCE_API pApiInstance;
struct oct612x_context context;
UINT32 aulEchoChanHndl[256];
int chanflags[256];
int ecmode[256];
@ -453,14 +417,18 @@ int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start
return 0;
}
unsigned int get_vpm450m_capacity(void *wc)
unsigned int get_vpm450m_capacity(struct device *device)
{
struct oct612x_context context;
UINT32 ulResult;
tOCT6100_API_GET_CAPACITY_PINS CapacityPins;
context.dev = device;
context.ops = &wct4xxp_oct612x_ops;
Oct6100ApiGetCapacityPinsDef(&CapacityPins);
CapacityPins.pProcessContext = wc;
CapacityPins.pProcessContext = &context;
CapacityPins.ulMemoryType = cOCT6100_MEM_TYPE_DDR;
CapacityPins.fEnableMemClkOut = TRUE;
CapacityPins.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
@ -474,7 +442,8 @@ unsigned int get_vpm450m_capacity(void *wc)
return CapacityPins.ulCapacityValue;
}
struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware)
struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
int numspans, const struct firmware *firmware)
{
tOCT6100_CHIP_OPEN *ChipOpen;
tOCT6100_GET_INSTANCE_SIZE InstanceSize;
@ -489,6 +458,8 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct f
return NULL;
memset(vpm450m, 0, sizeof(struct vpm450m));
vpm450m->context.dev = device;
vpm450m->context.ops = &wct4xxp_oct612x_ops;
if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
kfree(vpm450m);
@ -517,7 +488,7 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct f
ChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ;
Oct6100GetInstanceSizeDef(&InstanceSize);
ChipOpen->pProcessContext = wc;
ChipOpen->pProcessContext = &vpm450m->context;
ChipOpen->pbyImageFile = firmware->data;
ChipOpen->ulImageSize = firmware->size;

View File

@ -25,6 +25,7 @@
#include <linux/firmware.h>
struct t4;
struct vpm450m;
/* From driver */
@ -32,8 +33,9 @@ unsigned int oct_get_reg(void *data, unsigned int reg);
void oct_set_reg(void *data, unsigned int reg, unsigned int val);
/* From vpm450m */
struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware);
unsigned int get_vpm450m_capacity(void *wc);
struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
int numspans, const struct firmware *firmware);
unsigned int get_vpm450m_capacity(struct device *device);
void vpm450m_setec(struct vpm450m *instance, int channel, int eclen);
void vpm450m_setdtmf(struct vpm450m *instance, int channel, int dtmfdetect, int dtmfmute);
int vpm450m_checkirq(struct vpm450m *vpm450m);

View File

@ -205,7 +205,8 @@ struct t13x_firm_header {
#include <linux/time.h>
#include <linux/version.h>
#include <linux/firmware.h>
#include "oct6100api/oct6100_api.h"
#include <oct612x.h>
#define ECHOCAN_NUM_CHANS 32
@ -219,8 +220,8 @@ struct t13x_firm_header {
#define OCT_TONEEVENT_BUFFER_SIZE 128
#define SOUT_STREAM 1
#define RIN_STREAM 0
#define SIN_STREAM 2
#define SIN_STREAM 2
#define OCT_OFFSET (wc->membase + 0x10000)
#define OCT_CONTROL_REG (OCT_OFFSET + 0)
#define OCT_DATA_REG (OCT_OFFSET + 0x4)
@ -247,6 +248,7 @@ static const struct dahdi_echocan_ops vpm_ec_ops = {
struct vpm450m {
tPOCT6100_INSTANCE_API pApiInstance;
struct oct612x_context context;
UINT32 aulEchoChanHndl[ECHOCAN_NUM_CHANS];
int ecmode[ECHOCAN_NUM_CHANS];
unsigned long chanflags[ECHOCAN_NUM_CHANS];
@ -334,115 +336,58 @@ static void oct_set_reg_indirect(void *data, uint32_t address, uint16_t val)
WARN_ON_ONCE(time_after_eq(jiffies, stop));
}
/* API for Octasic access */
UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
static int t13x_oct612x_write(struct oct612x_context *context,
u32 address, u16 value)
{
/* Why couldn't they just take a timeval like everyone else? */
struct timeval tv;
unsigned long long total_usecs;
unsigned int mask = ~0;
do_gettimeofday(&tv);
total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
(((unsigned long long)(tv.tv_usec)));
f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
return cOCT6100_ERR_OK;
oct_set_reg_indirect(dev_get_drvdata(context->dev), address, value);
return 0;
}
UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern,
UINT32 f_ulLength)
static int t13x_oct612x_read(struct oct612x_context *context, u32 address,
u16 *value)
{
memset(f_pAddress, f_ulPattern, f_ulLength);
return cOCT6100_ERR_OK;
*value = oct_get_reg_indirect(dev_get_drvdata(context->dev), address);
return 0;
}
UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource,
UINT32 f_ulLength)
static int t13x_oct612x_write_smear(struct oct612x_context *context,
u32 address, u16 value, size_t count)
{
memcpy(f_pDestination, f_pSource, f_ulLength);
return cOCT6100_ERR_OK;
unsigned int i;
struct t13x *wc = dev_get_drvdata(context->dev);
for (i = 0; i < count; ++i)
oct_set_reg_indirect(wc, address + (i << 1), value);
return 0;
}
UINT32 Oct6100UserCreateSerializeObject(
tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
static int t13x_oct612x_write_burst(struct oct612x_context *context,
u32 address, const u16 *buffer,
size_t count)
{
return cOCT6100_ERR_OK;
unsigned int i;
struct t13x *wc = dev_get_drvdata(context->dev);
for (i = 0; i < count; ++i)
oct_set_reg_indirect(wc, address + (i << 1), buffer[i]);
return 0;
}
UINT32 Oct6100UserDestroySerializeObject(
tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
static int t13x_oct612x_read_burst(struct oct612x_context *context,
u32 address, u16 *buffer, size_t count)
{
#ifdef OCTASIC_DEBUG
pr_debug("I should never be called! (destroy serialize object)\n");
#endif
return cOCT6100_ERR_OK;
unsigned int i;
struct t13x *wc = dev_get_drvdata(context->dev);
for (i = 0; i < count; ++i)
buffer[i] = oct_get_reg_indirect(wc, address + (i << 1));
return 0;
}
UINT32 Oct6100UserSeizeSerializeObject(
tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserReleaseSerializeObject(
tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
{
oct_set_reg_indirect(f_pWriteParams->pProcessContext,
f_pWriteParams->ulWriteAddress,
f_pWriteParams->usWriteData);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteSmearApi(
tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
{
unsigned int x;
for (x = 0; x < f_pSmearParams->ulWriteLength; x++) {
oct_set_reg_indirect(f_pSmearParams->pProcessContext,
f_pSmearParams->ulWriteAddress + (x << 1),
f_pSmearParams->usWriteData);
}
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteBurstApi(
tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
{
unsigned int x;
for (x = 0; x < f_pBurstParams->ulWriteLength; x++) {
oct_set_reg_indirect(f_pBurstParams->pProcessContext,
f_pBurstParams->ulWriteAddress + (x << 1),
f_pBurstParams->pusWriteData[x]);
}
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
{
*(f_pReadParams->pusReadData) = oct_get_reg_indirect(
f_pReadParams->pProcessContext,
f_pReadParams->ulReadAddress);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
{
unsigned int x;
for (x = 0; x < f_pBurstParams->ulReadLength; x++) {
f_pBurstParams->pusReadData[x] = oct_get_reg_indirect(
f_pBurstParams->pProcessContext,
f_pBurstParams->ulReadAddress + (x << 1));
}
return cOCT6100_ERR_OK;
}
static const struct oct612x_ops t13x_oct612x_ops = {
.write = t13x_oct612x_write,
.read = t13x_oct612x_read,
.write_smear = t13x_oct612x_write_smear,
.write_burst = t13x_oct612x_write_burst,
.read_burst = t13x_oct612x_read_burst,
};
static void vpm450m_setecmode(struct vpm450m *vpm450m, int channel, int mode)
{
@ -615,6 +560,9 @@ static struct vpm450m *init_vpm450m(struct t13x *wc, int isalaw,
return NULL;
}
vpm450m->context.dev = &wc->dev->dev;
vpm450m->context.ops = &t13x_oct612x_ops;
ChipOpen = kzalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL);
if (!ChipOpen) {
dev_info(&wc->dev->dev, "Unable to allocate ChipOpen\n");
@ -637,7 +585,7 @@ static struct vpm450m *init_vpm450m(struct t13x *wc, int isalaw,
ECHOCAN_NUM_CHANS);
Oct6100ChipOpenDef(ChipOpen);
ChipOpen->pProcessContext = (void *)wc;
ChipOpen->pProcessContext = &vpm450m->context;
/* Change default parameters as needed */
/* upclk oscillator is at 33.33 Mhz */