summaryrefslogtreecommitdiff
path: root/kernel/wctdm24xxp/GpakCust.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-02-04 23:00:48 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-02-04 23:00:48 +0000
commit7e068801fbf82413ac0a5e63e586c268bd457434 (patch)
tree9b61e9a4e07167e0b7d347e4336245724befa29c /kernel/wctdm24xxp/GpakCust.c
parent29daeebad888269fa0ee2ca7e54e238c8498ca2d (diff)
Move kernel stuff to under kernel/
(merged branch /zaptel/team/tzafrir/move ) Closes issue #7117. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@3793 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'kernel/wctdm24xxp/GpakCust.c')
-rw-r--r--kernel/wctdm24xxp/GpakCust.c476
1 files changed, 476 insertions, 0 deletions
diff --git a/kernel/wctdm24xxp/GpakCust.c b/kernel/wctdm24xxp/GpakCust.c
new file mode 100644
index 0000000..23f2096
--- /dev/null
+++ b/kernel/wctdm24xxp/GpakCust.c
@@ -0,0 +1,476 @@
+/*
+ * 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. The standard
+ * GPL disclaimer is given inline below for your convenience.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/version.h>
+#include <linux/delay.h>
+#include <asm/semaphore.h>
+
+#include "zaptel.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;
+}
+
+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;
+}
+
+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;
+}
+
+int wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
+{
+ struct vpm150m_cmd *hit = 0;
+ 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;
+}
+
+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("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("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] = {0};
+ 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("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("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)
+ down_interruptible(&vpm->sem);
+ }
+}
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * 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
+}