summaryrefslogtreecommitdiff
path: root/drivers/tdm/device
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tdm/device')
-rw-r--r--drivers/tdm/device/Kconfig7
-rw-r--r--drivers/tdm/device/Makefile4
-rw-r--r--drivers/tdm/device/fsl_ucc_tdm.c1034
-rw-r--r--drivers/tdm/device/fsl_ucc_tdm.h165
4 files changed, 1208 insertions, 2 deletions
diff --git a/drivers/tdm/device/Kconfig b/drivers/tdm/device/Kconfig
index 9fd1b06..af6a710 100644
--- a/drivers/tdm/device/Kconfig
+++ b/drivers/tdm/device/Kconfig
@@ -12,4 +12,11 @@ config TDM_FSL
is found in various Freescale SOCs viz MPC8315, P1020. The TDM driver
basically multiplexes and demultiplexes data from different channels.
The TDM can interface SLIC kind of devices.
+
+config FSL_UCC_TDM
+ tristate "UCC TDM driver for Freescale QE engine"
+ depends on FSL_SOC || CONFIG_QE
+ ---help---
+ This is a driver for Freescale QE UCC working with TDM interface.
+
endmenu
diff --git a/drivers/tdm/device/Makefile b/drivers/tdm/device/Makefile
index 4156d7f..d41d10c 100644
--- a/drivers/tdm/device/Makefile
+++ b/drivers/tdm/device/Makefile
@@ -2,8 +2,8 @@
# Makefile for the TDM device drivers.
#
-obj-y += tdm_fsl.o
-
+obj-$(CONFIG_TDM_FSL) += tdm_fsl.o
+obj-$(CONFIG_FSL_UCC_TDM) += fsl_ucc_tdm.o
#ifeq ($(CONFIG_TDM_DEBUG_BUS),y)
#EXTRA_CFLAGS += -DDEBUG
#endif
diff --git a/drivers/tdm/device/fsl_ucc_tdm.c b/drivers/tdm/device/fsl_ucc_tdm.c
new file mode 100644
index 0000000..36e4299
--- /dev/null
+++ b/drivers/tdm/device/fsl_ucc_tdm.c
@@ -0,0 +1,1034 @@
+/*
+ * Freescale QUICC Engine TDM Device Driver
+ *
+ * Copyright 2011-2012 Freescale Semiconductor, Inc.
+ *
+ * Author: Haiying Wang <Haiying.Wang@freescale.com>
+ * Kai Jiang <Kai.Jiang@freescale.com>
+ *
+ * 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.
+ *
+ * This driver adds support for TDM devices via Freescale's QUICC Engine.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/tdm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_soc.h>
+#include <linux/slab.h>
+#include "fsl_ucc_tdm.h"
+
+#define DRV_DESC "Freescale QE UCC TDM Driver"
+#define DRV_NAME "ucc_tdm"
+
+#undef DEBUG
+
+static struct ucc_tdm_info utdm_primary_info = {
+ .uf_info = {
+ .tsa = 1,
+ .cdp = 1,
+ .cds = 1,
+ .ctsp = 1,
+ .ctss = 1,
+ .revd = 0,
+ .urfs = 256,
+ .utfs = 256,
+ .urfet = 128,
+ .urfset = 192,
+ .utfet = 128,
+ .utftt = 0x40,
+ .ufpt = 256,
+ .ttx_trx = UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_TRANSPARENT,
+ .tenc = UCC_FAST_TX_ENCODING_NRZ,
+ .renc = UCC_FAST_RX_ENCODING_NRZ,
+ .tcrc = UCC_FAST_16_BIT_CRC,
+ .synl = UCC_FAST_SYNC_LEN_NOT_USED,
+ },
+
+ .si_info = {
+ .simr_rfsd = 1, /* pq_mds_t1 card need 1 bit delay */
+ .simr_tfsd = 0,
+ .simr_crt = 0,
+ .simr_sl = 0,
+ .simr_ce = 1,
+ .simr_fe = 1,
+ .simr_gm = 0,
+ },
+};
+
+static struct ucc_tdm_info utdm_info[MAX_TDM_NUM];
+static int siram_init_flag;
+
+#ifdef DEBUG
+static void dump_siram(struct ucc_tdm_private *priv)
+{
+ int i;
+ u16 *siram = priv->siram;
+
+ dev_info(priv->dev, "Dump the SI RX RAM\n");
+ for (i = 0; i < priv->num_of_ts; i++) {
+ pr_info("%04x ", siram[priv->siram_entry_id * 32 + i]);
+ if ((i + 1) % 4)
+ pr_info("\n");
+ }
+
+ dev_info(priv->dev, "Dump the SI TX RAM\n");
+ for (i = 0; i < priv->num_of_ts; i++) {
+ pr_info("%04x ", siram[priv->siram_entry_id * 32 + 0x200 + i]);
+ if ((i + 1) % 4)
+ pr_info("\n");
+ }
+}
+
+static void mem_disp(u8 *addr, int size)
+{
+ void *i;
+ int size16_aling = (size >> 4) << 4;
+ int size4_aling = (size >> 2) << 2;
+ int not_align = 0;
+ if (size % 16)
+ not_align = 1;
+
+ for (i = addr; i < addr + size16_aling; i += 16) {
+ u32 *i32 = i;
+
+ pr_info("0x%08p: %08x %08x %08x %08x\r\n",
+ i32, i32[0], i32[1], i32[2], i32[3]);
+ }
+
+ if (not_align == 1)
+ pr_info("0x%08p: ", i);
+ for (; i < addr + size4_aling; i += 4)
+ pr_info("%08x ", *((u32 *) (i)));
+ for (; i < addr + size; i++)
+ pr_info("%02x", *((u8 *) (i)));
+ if (not_align == 1)
+ pr_info("\r\n");
+}
+
+static void dump_ucc(struct ucc_tdm_private *priv)
+{
+ struct ucc_transparent_param *ucc_pram;
+ ucc_pram = priv->ucc_pram;
+
+ dev_info(priv->dev, "DumpiniCC %d Registers\n",
+ priv->ut_info->uf_info.ucc_num);
+ ucc_fast_dump_regs(priv->uccf);
+ dev_info(priv->dev, "Dumping UCC %d Parameter RAM\n",
+ priv->ut_info->uf_info.ucc_num);
+ dev_info(priv->dev, "rbase = 0x%x\n", in_be32(&ucc_pram->rbase));
+ dev_info(priv->dev, "rbptr = 0x%x\n", in_be32(&ucc_pram->rbptr));
+ dev_info(priv->dev, "mrblr = 0x%x\n", in_be16(&ucc_pram->mrblr));
+ dev_info(priv->dev, "rbdlen = 0x%x\n", in_be16(&ucc_pram->rbdlen));
+ dev_info(priv->dev, "rbdstat = 0x%x\n", in_be16(&ucc_pram->rbdstat));
+ dev_info(priv->dev, "rstate = 0x%x\n", in_be32(&ucc_pram->rstate));
+ dev_info(priv->dev, "rdptr = 0x%x\n", in_be32(&ucc_pram->rdptr));
+ dev_info(priv->dev, "riptr = 0x%x\n", in_be16(&ucc_pram->riptr));
+ dev_info(priv->dev, "tbase = 0x%x\n", in_be32(&ucc_pram->tbase));
+ dev_info(priv->dev, "tbptr = 0x%x\n", in_be32(&ucc_pram->tbptr));
+ dev_info(priv->dev, "tbdlen = 0x%x\n", in_be16(&ucc_pram->tbdlen));
+ dev_info(priv->dev, "tbdstat = 0x%x\n", in_be16(&ucc_pram->tbdstat));
+ dev_info(priv->dev, "tstate = 0x%x\n", in_be32(&ucc_pram->tstate));
+ dev_info(priv->dev, "tdptr = 0x%x\n", in_be32(&ucc_pram->tdptr));
+ dev_info(priv->dev, "tiptr = 0x%x\n", in_be16(&ucc_pram->tiptr));
+ dev_info(priv->dev, "rcrc = 0x%x\n", in_be32(&ucc_pram->rcrc));
+ dev_info(priv->dev, "tcrc = 0x%x\n", in_be32(&ucc_pram->tcrc));
+ dev_info(priv->dev, "c_mask = 0x%x\n", in_be32(&ucc_pram->c_mask));
+ dev_info(priv->dev, "c_pers = 0x%x\n", in_be32(&ucc_pram->c_pres));
+ dev_info(priv->dev, "disfc = 0x%x\n", in_be16(&ucc_pram->disfc));
+ dev_info(priv->dev, "crcec = 0x%x\n", in_be16(&ucc_pram->crcec));
+}
+
+static void dump_bds(struct ucc_tdm_private *priv)
+{
+ int length;
+
+ if (priv->tx_bd) {
+ length = sizeof(struct qe_bd) * NUM_OF_BUF;
+ dev_info(priv->dev, " Dump tx BDs\n");
+ mem_disp((u8 *)priv->tx_bd, length);
+ }
+
+ if (priv->rx_bd) {
+ length = sizeof(struct qe_bd) * NUM_OF_BUF;
+ dev_info(priv->dev, " Dump rx BDs\n");
+ mem_disp((u8 *)priv->rx_bd, length);
+ }
+
+}
+
+static void dump_priv(struct ucc_tdm_private *priv)
+{
+ dev_info(priv->dev, "ut_info = 0x%x\n", (u32)priv->ut_info);
+ dev_info(priv->dev, "uccf = 0x%x\n", (u32)priv->uccf);
+ dev_info(priv->dev, "uf_regs = 0x%x\n", (u32)priv->uf_regs);
+ dev_info(priv->dev, "si_regs = 0x%x\n", (u32)priv->si_regs);
+ dev_info(priv->dev, "ucc_pram = 0x%x\n", (u32)priv->ucc_pram);
+ dev_info(priv->dev, "tdm_port = 0x%x\n", (u32)priv->tdm_port);
+ dev_info(priv->dev, "siram_entry_id = 0x%x\n", priv->siram_entry_id);
+ dev_info(priv->dev, "siram = 0x%x\n", (u32)priv->siram);
+ dev_info(priv->dev, "tdm_mode = 0x%x\n", (u32)priv->tdm_mode);
+ dev_info(priv->dev, "tdm_framer_type; = 0x%x\n",
+ (u32)priv->tdm_framer_type);
+ dev_info(priv->dev, "rx_buffer; = 0x%x\n", (u32)priv->rx_buffer);
+ dev_info(priv->dev, "tx_buffer; = 0x%x\n", (u32)priv->tx_buffer);
+ dev_info(priv->dev, "dma_rx_addr; = 0x%x\n", (u32)priv->dma_rx_addr);
+ dev_info(priv->dev, "dma_tx_addr; = 0x%x\n", (u32)priv->dma_tx_addr);
+ dev_info(priv->dev, "tx_bd; = 0x%x\n", (u32)priv->tx_bd);
+ dev_info(priv->dev, "rx_bd; = 0x%x\n", (u32)priv->rx_bd);
+ dev_info(priv->dev, "phase_rx = 0x%x\n", (u32)priv->phase_rx);
+ dev_info(priv->dev, "phase_tx = 0x%x\n", (u32)priv->phase_tx);
+ dev_info(priv->dev, "ucc_pram_offset = 0x%x\n", priv->ucc_pram_offset);
+ dev_info(priv->dev, "tx_bd_offset = 0x%x\n", priv->tx_bd_offset);
+ dev_info(priv->dev, "rx_bd_offset = 0x%x\n", priv->rx_bd_offset);
+
+}
+
+#endif /* DEBUG */
+
+static void init_si(struct ucc_tdm_private *priv)
+{
+ struct si1 __iomem *si_regs;
+ u16 __iomem *siram;
+ u16 siram_entry_valid;
+ u16 siram_entry_closed;
+ u16 ucc_num;
+ u8 csel;
+ u16 sixmr;
+ u16 tdm_port;
+ u32 siram_entry_id;
+ u32 mask;
+ int i;
+
+ si_regs = priv->si_regs;
+ siram = priv->siram;
+ ucc_num = priv->ut_info->uf_info.ucc_num;
+ tdm_port = priv->tdm_port;
+ siram_entry_id = priv->siram_entry_id;
+
+ /* set siram table */
+ csel = (ucc_num < 4) ? ucc_num + 9 : ucc_num - 3;
+
+ siram_entry_valid = SIR_CSEL(csel) | SIR_BYTE | SIR_CNT(0);
+ siram_entry_closed = SIR_IDLE | SIR_BYTE | SIR_CNT(0);
+
+ for (i = 0; i < priv->num_of_ts; i++) {
+ mask = 0x01 << i;
+
+ if (priv->tx_ts_mask & mask)
+ out_be16(&siram[siram_entry_id * 32 + i],
+ siram_entry_valid);
+ else
+ out_be16(&siram[siram_entry_id * 32 + i],
+ siram_entry_closed);
+
+ if (priv->rx_ts_mask & mask)
+ out_be16(&siram[siram_entry_id * 32 + 0x200 + i],
+ siram_entry_valid);
+ else
+ out_be16(&siram[siram_entry_id * 32 + 0x200 + i],
+ siram_entry_closed);
+ }
+
+ setbits16(&siram[(siram_entry_id * 32) + (priv->num_of_ts - 1)],
+ SIR_LAST);
+ setbits16(&siram[(siram_entry_id * 32) + 0x200 + (priv->num_of_ts - 1)],
+ SIR_LAST);
+
+ /* Set SIxMR register */
+ sixmr = SIMR_SAD(siram_entry_id);
+
+ sixmr &= ~SIMR_SDM_MASK;
+
+ if (priv->tdm_mode == TDM_INTERNAL_LOOPBACK)
+ sixmr |= SIMR_SDM_INTERNAL_LOOPBACK;
+ else
+ sixmr |= SIMR_SDM_NORMAL;
+
+ sixmr |= SIMR_RFSD(priv->ut_info->si_info.simr_rfsd) |
+ SIMR_TFSD(priv->ut_info->si_info.simr_tfsd);
+
+ if (priv->ut_info->si_info.simr_crt)
+ sixmr |= SIMR_CRT;
+ if (priv->ut_info->si_info.simr_sl)
+ sixmr |= SIMR_SL;
+ if (priv->ut_info->si_info.simr_ce)
+ sixmr |= SIMR_CE;
+ if (priv->ut_info->si_info.simr_fe)
+ sixmr |= SIMR_FE;
+ if (priv->ut_info->si_info.simr_gm)
+ sixmr |= SIMR_GM;
+
+ switch (tdm_port) {
+ case 0:
+ out_be16(&si_regs->sixmr1[0], sixmr);
+ break;
+ case 1:
+ out_be16(&si_regs->sixmr1[1], sixmr);
+ break;
+ case 2:
+ out_be16(&si_regs->sixmr1[2], sixmr);
+ break;
+ case 3:
+ out_be16(&si_regs->sixmr1[3], sixmr);
+ break;
+ default:
+ dev_err(priv->dev, "can not find tdm sixmr reg\n");
+ break;
+ }
+
+#ifdef DEBUG
+ dump_siram(priv);
+#endif
+
+}
+static int utdm_init(struct ucc_tdm_private *priv)
+{
+ struct ucc_tdm_info *ut_info;
+ struct ucc_fast_info *uf_info;
+ u32 cecr_subblock;
+ u32 bd_status;
+ int ret, i;
+ void *bd_buffer;
+ dma_addr_t bd_dma_addr;
+ u32 riptr;
+ u32 tiptr;
+
+ ut_info = priv->ut_info;
+ uf_info = &ut_info->uf_info;
+
+ if (priv->tdm_framer_type == TDM_FRAMER_T1)
+ priv->num_of_ts = 24;
+ if (priv->tdm_framer_type == TDM_FRAMER_E1)
+ priv->num_of_ts = 32;
+
+ uf_info->uccm_mask = (u32) (UCC_TRANS_UCCE_RXB << 16);
+
+ if (ucc_fast_init(uf_info, &priv->uccf)) {
+ dev_err(priv->dev, "Failed to init uccf.");
+ return -ENOMEM;
+ }
+
+ priv->uf_regs = priv->uccf->uf_regs;
+ ucc_fast_disable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);
+
+ /* Initialize SI */
+ init_si(priv);
+
+ /* Write to QE CECR, UCCx channel to Stop Transmission */
+ cecr_subblock = ucc_fast_get_qe_cr_subblock(uf_info->ucc_num);
+ ret = qe_issue_cmd(QE_STOP_TX, cecr_subblock,
+ (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
+
+ /* Set UPSMR normal mode */
+ out_be32(&priv->uf_regs->upsmr, 0);
+
+ /* Alloc Rx BD */
+ priv->rx_bd_offset = qe_muram_alloc(NUM_OF_BUF * sizeof(struct qe_bd),
+ QE_ALIGNMENT_OF_BD);
+ if (IS_ERR_VALUE(priv->rx_bd_offset)) {
+ dev_err(priv->dev, "Cannot allocate MURAM memory for RxBDs\n");
+ ret = -ENOMEM;
+ goto rxbd_alloc_error;
+ }
+
+ /* Alloc Tx BD */
+ priv->tx_bd_offset = qe_muram_alloc(NUM_OF_BUF * sizeof(struct qe_bd),
+ QE_ALIGNMENT_OF_BD);
+ if (IS_ERR_VALUE(priv->tx_bd_offset)) {
+ dev_err(priv->dev, "Cannot allocate MURAM memory for TxBDs\n");
+ ret = -ENOMEM;
+ goto txbd_alloc_error;
+ }
+
+ priv->tx_bd = qe_muram_addr(priv->tx_bd_offset);
+ priv->rx_bd = qe_muram_addr(priv->rx_bd_offset);
+
+ /* Alloc parameter ram for ucc transparent */
+ priv->ucc_pram_offset = qe_muram_alloc(sizeof(priv->ucc_pram),
+ ALIGNMENT_OF_UCC_TRANS_PRAM);
+
+ if (IS_ERR_VALUE(priv->ucc_pram_offset)) {
+ dev_err(priv->dev, "Can not allocate MURAM for hdlc prameter.\n");
+ return -ENOMEM;
+ goto pram_alloc_error;
+ }
+
+ /* init parameter base */
+ cecr_subblock = ucc_fast_get_qe_cr_subblock(uf_info->ucc_num);
+ ret = qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, cecr_subblock,
+ QE_CR_PROTOCOL_UNSPECIFIED, priv->ucc_pram_offset);
+
+ priv->ucc_pram = (struct ucc_transparent_param __iomem *)
+ qe_muram_addr(priv->ucc_pram_offset);
+
+ /* Zero out parameter ram */
+ memset_io(priv->ucc_pram, 0, sizeof(struct ucc_transparent_param));
+
+ /* Alloc riptr, tiptr */
+ riptr = qe_muram_alloc(32, 32);
+ if (IS_ERR_VALUE(riptr)) {
+ dev_err(priv->dev, "Cannot allocate MURAM mem for Receive"
+ " internal temp data pointer\n");
+ ret = -ENOMEM;
+ goto riptr_alloc_error;
+ }
+
+ tiptr = qe_muram_alloc(32, 32);
+ if (IS_ERR_VALUE(tiptr)) {
+ dev_err(priv->dev, "Cannot allocate MURAM mem for transmit"
+ " internal temp data pointer\n");
+ ret = -ENOMEM;
+ goto tiptr_alloc_error;
+ }
+
+ /* Set RIPTR, TIPTR */
+ out_be16(&priv->ucc_pram->riptr, (u16)riptr);
+ out_be16(&priv->ucc_pram->tiptr, (u16)tiptr);
+
+ /* Set MRBLR */
+ out_be16(&priv->ucc_pram->mrblr, (u16)MAX_RX_BUF_LENGTH);
+
+ /* QE couldn't support >= 4G */
+ if (cpm_muram_dma(priv->rx_bd) & ~(0xffffffffULL) &&
+ cpm_muram_dma(priv->tx_bd) & ~(0xffffffffULL)) {
+ dev_err(priv->dev, "QE address couldn't support > 4G");
+ ret = -EFAULT;
+ goto tiptr_alloc_error;
+ }
+ /* Set RBASE, TBASE */
+ out_be32(&priv->ucc_pram->rbase, (u32)cpm_muram_dma(priv->rx_bd));
+ out_be32(&priv->ucc_pram->tbase, (u32)cpm_muram_dma(priv->tx_bd));
+
+ /* Set RSTATE, TSTATE */
+ out_be32(&priv->ucc_pram->rstate, 0x30000000);
+ out_be32(&priv->ucc_pram->tstate, 0x30000000);
+
+ /* Set C_MASK, C_PRES for 16bit CRC */
+ out_be32(&priv->ucc_pram->c_mask, 0x0000F0B8);
+ out_be32(&priv->ucc_pram->c_pres, 0x0000FFFF);
+
+ out_be16(&priv->ucc_pram->res0, 0);
+ for (i = 0; i < 4; i++)
+ out_be32(&priv->ucc_pram->res4[i], 0x0);
+
+ /* Get BD buffer */
+ bd_buffer = dma_alloc_coherent(priv->dev,
+ 2 * NUM_OF_BUF * MAX_RX_BUF_LENGTH,
+ &bd_dma_addr, GFP_KERNEL);
+
+ if (!bd_buffer) {
+ dev_err(priv->dev, "Could not allocate buffer descriptors\n");
+ return -ENOMEM;
+ }
+
+ memset(bd_buffer, 0, 2 * NUM_OF_BUF * MAX_RX_BUF_LENGTH);
+
+ priv->rx_buffer = bd_buffer;
+ priv->tx_buffer = bd_buffer + NUM_OF_BUF * MAX_RX_BUF_LENGTH;
+
+ priv->dma_rx_addr = bd_dma_addr;
+ priv->dma_tx_addr = bd_dma_addr + NUM_OF_BUF * MAX_RX_BUF_LENGTH;
+
+ for (i = 0; i < NUM_OF_BUF; i++) {
+ if (i < (NUM_OF_BUF - 1))
+ bd_status = R_E | R_I | R_CM;
+ else
+ bd_status = R_E | R_I | R_W | R_CM;
+
+ out_be32((u32 *)(priv->rx_bd + i), bd_status);
+ out_be32(&priv->rx_bd[i].buf, priv->dma_rx_addr
+ + i * MAX_RX_BUF_LENGTH);
+
+ if (i < (NUM_OF_BUF - 1))
+ bd_status = T_I;
+ else
+ bd_status = T_I | T_W;
+
+ out_be32((u32 *)(priv->tx_bd + i), bd_status);
+ out_be32(&priv->tx_bd[i].buf, priv->dma_tx_addr
+ + i * MAX_RX_BUF_LENGTH);
+ }
+
+ priv->phase_rx = 0;
+ priv->phase_tx = 0;
+
+ return 0;
+
+tiptr_alloc_error:
+ qe_muram_free(riptr);
+riptr_alloc_error:
+ qe_muram_free(priv->ucc_pram_offset);
+pram_alloc_error:
+ qe_muram_free(priv->tx_bd_offset);
+txbd_alloc_error:
+ qe_muram_free(priv->rx_bd_offset);
+rxbd_alloc_error:
+ ucc_fast_free(priv->uccf);
+
+ return ret;
+}
+
+static int ucc_tdm_read(struct tdm_adapter *adap, u8 *tdm_buffer, u32 len)
+{
+
+ struct ucc_tdm_private *priv = tdm_get_adapdata(adap);
+ u8 phase_rx;
+ u32 byte_copy;
+ u8 *recv_buf;
+
+ wait_event_interruptible(priv->tdm_queue,
+ priv->tdm_queue_flag != false);
+ priv->tdm_queue_flag = false;
+
+ if (priv->phase_rx == 0)
+ phase_rx = NUM_OF_BUF - 1;
+ else
+ phase_rx = priv->phase_rx - 1;
+
+ recv_buf = priv->rx_buffer + phase_rx * MAX_RX_BUF_LENGTH;
+
+ if (len > MAX_RX_BUF_LENGTH)
+ byte_copy = MAX_RX_BUF_LENGTH;
+ else
+ byte_copy = len;
+
+ memcpy(tdm_buffer, recv_buf, byte_copy);
+
+ return byte_copy;
+
+}
+
+
+static int ucc_tdm_write(struct tdm_adapter *adap, u8 *write_buf,
+ unsigned int len)
+{
+ struct ucc_tdm_private *priv = tdm_get_adapdata(adap);
+ struct qe_bd __iomem *bd;
+ u32 bd_stat_len;
+ u8 *tdm_send_buf;
+ u32 copy_len;
+ int i, ret;
+ u32 buf_num;
+
+ buf_num = len / MAX_RX_BUF_LENGTH;
+ if (len % MAX_RX_BUF_LENGTH)
+ buf_num += 1;
+
+ if (buf_num > NUM_OF_BUF)
+ return -EINVAL;
+
+ for (i = 0; i < buf_num; i++) {
+
+ if (priv->phase_tx == NUM_OF_BUF)
+ priv->phase_tx = 0;
+
+ bd = (priv->tx_bd + priv->phase_tx);
+ bd_stat_len = in_be32((u32 __iomem *)bd);
+ tdm_send_buf = priv->tx_buffer +
+ priv->phase_tx * MAX_RX_BUF_LENGTH;
+
+ /* the last buf to copy */
+ if (i == (buf_num - 1))
+ copy_len = len - i * MAX_RX_BUF_LENGTH;
+ else
+ copy_len = MAX_RX_BUF_LENGTH;
+
+ ret = spin_event_timeout(((bd_stat_len =
+ in_be32((u32 __iomem *)bd)) & T_R) != T_R ,
+ 1000000, 500);
+ if (!ret) {
+ dev_err(priv->dev, "TDM write data error!\n");
+ return -EFAULT;
+ }
+
+ memset(tdm_send_buf, 0xff, MAX_RX_BUF_LENGTH);
+
+ memcpy(tdm_send_buf, write_buf, copy_len);
+
+ bd_stat_len &= ~(T_L | BD_LEN_MASK);
+ if (i == (buf_num - 1))
+ out_be32((u32 __iomem *)(bd),
+ bd_stat_len | T_R | T_L | T_I | copy_len);
+ else
+ out_be32((u32 __iomem *)(bd),
+ bd_stat_len | T_R | T_I | copy_len);
+
+ priv->phase_tx++;
+ }
+
+ return 0;
+}
+
+static irqreturn_t ucc_tdm_irq_handler(int irq, void *dev_id)
+{
+ struct ucc_tdm_private *priv = (struct ucc_tdm_private *)dev_id;
+ struct ucc_fast_private *uccf;
+ struct ucc_tdm_info *ut_info;
+ u32 ucce;
+ u32 uccm;
+
+ ut_info = priv->ut_info;
+ uccf = priv->uccf;
+
+ ucce = in_be32(uccf->p_ucce);
+ uccm = in_be32(uccf->p_uccm);
+
+ if ((ucce >> 16) & UCC_TRANS_UCCE_RXB) {
+ if (priv->phase_rx == NUM_OF_BUF - 1)
+ priv->phase_rx = 0;
+ else
+ priv->phase_rx++;
+
+ priv->tdm_queue_flag = true;
+ wake_up_interruptible(&priv->tdm_queue);
+
+ }
+
+ out_be32(uccf->p_ucce, ucce);
+
+ return IRQ_HANDLED;
+
+}
+
+static int utdm_start(struct tdm_adapter *adap)
+{
+ u32 cecr_subblock;
+ struct ucc_tdm_private *priv = tdm_get_adapdata(adap);
+
+ if (priv->tdm_busy != 1) {
+ if (request_irq(priv->ut_info->uf_info.irq, ucc_tdm_irq_handler,
+ 0, "tdm", (void *)priv)) {
+ dev_err(priv->dev, "request_irq for ucc tdm failed\n");
+ return -ENODEV;
+ }
+ cecr_subblock = ucc_fast_get_qe_cr_subblock(
+ priv->ut_info->uf_info.ucc_num);
+
+ qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock,
+ (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
+
+ ucc_fast_enable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);
+
+ /* Enable the TDM port */
+ priv->si_regs->siglmr1_h |= (0x1 << priv->tdm_port);
+ priv->phase_rx = 0;
+ priv->phase_tx = 0;
+ priv->tdm_busy = 1;
+ } else
+ dev_err(priv->dev, "TDM IS RUNNING!\n");
+
+#ifdef DEBUG
+ dump_priv(priv);
+ dump_ucc(priv);
+ dump_bds(priv);
+#endif
+
+ return 0;
+}
+
+static void utdm_memclean(struct ucc_tdm_private *priv)
+{
+ qe_muram_free(priv->ucc_pram->riptr);
+ qe_muram_free(priv->ucc_pram->tiptr);
+
+ if (priv->rx_bd) {
+ qe_muram_free(priv->rx_bd_offset);
+ priv->rx_bd = NULL;
+ priv->rx_bd_offset = 0;
+ }
+
+ if (priv->tx_bd) {
+ qe_muram_free(priv->tx_bd_offset);
+ priv->tx_bd = NULL;
+ priv->tx_bd_offset = 0;
+ }
+
+ if (priv->ucc_pram) {
+ qe_muram_free(priv->ucc_pram_offset);
+ priv->ucc_pram = NULL;
+ priv->ucc_pram_offset = 0;
+ }
+
+ if (priv->uf_regs) {
+ iounmap(priv->uf_regs);
+ priv->uf_regs = NULL;
+ }
+
+ if (priv->uccf) {
+ ucc_fast_free(priv->uccf);
+ priv->uccf = NULL;
+ }
+
+ if (priv->rx_buffer) {
+ dma_free_coherent(priv->dev,
+ 2 * NUM_OF_BUF * MAX_RX_BUF_LENGTH,
+ priv->rx_buffer, priv->dma_rx_addr);
+ priv->rx_buffer = NULL;
+ priv->dma_rx_addr = 0;
+ }
+}
+
+static int utdm_stop(struct tdm_adapter *adap)
+{
+ struct ucc_tdm_private *priv = tdm_get_adapdata(adap);
+ u32 cecr_subblock;
+
+ cecr_subblock = ucc_fast_get_qe_cr_subblock(
+ priv->ut_info->uf_info.ucc_num);
+
+ qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock,
+ (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
+ qe_issue_cmd(QE_CLOSE_RX_BD, cecr_subblock,
+ (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
+
+ priv->si_regs->siglmr1_h &= ~(0x1 << priv->tdm_port);
+ ucc_fast_disable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);
+
+ free_irq(priv->ut_info->uf_info.irq, priv);
+ priv->tdm_busy = 0;
+
+ return 0;
+}
+
+static const struct tdm_adapt_algorithm tdm_algo = {
+ .tdm_read_simple = ucc_tdm_read,
+ .tdm_write_simple = ucc_tdm_write,
+ .tdm_enable = utdm_start,
+ .tdm_disable = utdm_stop,
+};
+
+static struct tdm_adapter ucc_tdm_ops = {
+ .owner = THIS_MODULE,
+ .algo = &tdm_algo,
+};
+
+static enum tdm_mode_t set_tdm_mode(const char *tdm_mode_type)
+{
+ if (strcasecmp(tdm_mode_type, "internal-loopback") == 0)
+ return TDM_INTERNAL_LOOPBACK;
+ else
+ return TDM_NORMAL;
+}
+
+
+static enum tdm_framer_t set_tdm_framer(const char *tdm_framer_type)
+{
+ if (strcasecmp(tdm_framer_type, "e1") == 0)
+ return TDM_FRAMER_E1;
+ else
+ return TDM_FRAMER_T1;
+}
+
+static void set_si_param(struct ucc_tdm_private *priv)
+{
+ struct si_mode_info *si_info = &priv->ut_info->si_info;
+
+ if (priv->tdm_mode == TDM_INTERNAL_LOOPBACK) {
+ si_info->simr_crt = 1;
+ si_info->simr_rfsd = 0;
+ }
+}
+
+static int ucc_tdm_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ucc_tdm_private *utdm_priv = NULL;
+ struct ucc_tdm_info *ut_info;
+ struct resource res;
+ int ucc_num;
+ const unsigned int *prop;
+ const char *sprop;
+ struct device_node *np2;
+ int ret;
+
+ prop = of_get_property(np, "cell-index", NULL);
+ if (!prop) {
+ dev_err(&pdev->dev, "Invalid ucc property\n");
+ return -ENODEV;
+ }
+
+ ucc_num = *prop - 1;
+ if ((ucc_num > 7) && (ucc_num < 0)) {
+ dev_err(&pdev->dev, ": Invalid UCC num\n");
+ return -EINVAL;
+ }
+
+ memcpy(&(utdm_info[ucc_num]), &utdm_primary_info,
+ sizeof(utdm_primary_info));
+
+ ut_info = &utdm_info[ucc_num];
+ ut_info->uf_info.ucc_num = ucc_num;
+
+ sprop = of_get_property(np, "rx-clock-name", NULL);
+ if (sprop) {
+ ut_info->uf_info.rx_clock = qe_clock_source(sprop);
+ if ((ut_info->uf_info.rx_clock < QE_CLK_NONE) ||
+ (ut_info->uf_info.rx_clock > QE_CLK24)) {
+ dev_err(&pdev->dev, "Invalid rx-clock-name property\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_err(&pdev->dev, "Invalid rx-clock-name property\n");
+ return -EINVAL;
+ }
+
+ sprop = of_get_property(np, "tx-clock-name", NULL);
+ if (sprop) {
+ ut_info->uf_info.tx_clock = qe_clock_source(sprop);
+ if ((ut_info->uf_info.tx_clock < QE_CLK_NONE) ||
+ (ut_info->uf_info.tx_clock > QE_CLK24)) {
+ dev_err(&pdev->dev, "Invalid tx-clock-name property\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_err(&pdev->dev, "Invalid tx-clock-name property\n");
+ return -EINVAL;
+ }
+
+ sprop = of_get_property(np, "fsl,rx-sync-clock", NULL);
+ if (sprop) {
+ ut_info->uf_info.rx_sync = qe_clock_source(sprop);
+ if ((ut_info->uf_info.rx_sync < QE_CLK_NONE) ||
+ (ut_info->uf_info.rx_sync > QE_RSYNC_PIN)) {
+ dev_err(&pdev->dev, "Invalid rx-sync-clock property\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_err(&pdev->dev, "Invalid rx-sync-clock property\n");
+ return -EINVAL;
+ }
+
+ sprop = of_get_property(np, "fsl,tx-sync-clock", NULL);
+ if (sprop) {
+ ut_info->uf_info.tx_sync = qe_clock_source(sprop);
+ if ((ut_info->uf_info.tx_sync < QE_CLK_NONE) ||
+ (ut_info->uf_info.tx_sync > QE_TSYNC_PIN)) {
+ dev_err(&pdev->dev, "Invalid tx-sync-clock property\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_err(&pdev->dev, "Invalid tx-sync-clock property\n");
+ return -EINVAL;
+ }
+
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret)
+ return -EINVAL;
+
+ ut_info->uf_info.regs = res.start;
+ ut_info->uf_info.irq = irq_of_parse_and_map(np, 0);
+
+ utdm_priv = kzalloc(sizeof(struct ucc_tdm_private), GFP_KERNEL);
+ if (!utdm_priv) {
+ ret = -ENOMEM;
+ dev_err(&pdev->dev, "No mem to alloc tdm private data\n");
+ goto err_alloc_priv;
+ }
+
+ dev_set_drvdata(&pdev->dev, utdm_priv);
+ utdm_priv->dev = &pdev->dev;
+
+ prop = of_get_property(np, "fsl,tx-timeslot", NULL);
+ if (!prop) {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "Invalid tx-timeslot property\n");
+ goto err_miss_property;
+ }
+ utdm_priv->tx_ts_mask = *prop;
+
+ prop = of_get_property(np, "fsl,rx-timeslot", NULL);
+ if (!prop) {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "Invalid rx-timeslot property\n");
+ goto err_miss_property;
+ }
+ utdm_priv->rx_ts_mask = *prop;
+
+ prop = of_get_property(np, "fsl,tdm-id", NULL);
+ if (!prop) {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "No fsl,tdm-id property for this UCC\n");
+ goto err_miss_property;
+ }
+ utdm_priv->tdm_port = *prop;
+ ut_info->uf_info.tdm_num = utdm_priv->tdm_port ;
+
+ prop = of_get_property(np, "fsl,tdm-mode", NULL);
+ if (!prop) {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "No tdm-mode property for UCC\n");
+ goto err_miss_property;
+ }
+ utdm_priv->tdm_mode = set_tdm_mode((const char *)prop);
+
+ prop = of_get_property(np, "fsl,tdm-framer-type", NULL);
+ if (!prop) {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "No tdm-framer-type property for UCC\n");
+ goto err_miss_property;
+ }
+ utdm_priv->tdm_framer_type = set_tdm_framer((const char *)prop);
+
+ prop = of_get_property(np, "fsl,siram-entry-id", NULL);
+ if (!prop) {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "No siram entry id for UCC\n");
+ goto err_miss_property;
+ }
+ utdm_priv->siram_entry_id = *(const u32 *)prop;
+
+ np2 = of_find_node_by_name(NULL, "si");
+ if (!np2) {
+ dev_err(&pdev->dev, "No si property\n");
+ goto err_miss_property;
+ }
+ of_address_to_resource(np2, 0, &res);
+ utdm_priv->si_regs = ioremap(res.start, res.end - res.start + 1);
+ of_node_put(np2);
+
+
+ np2 = of_find_node_by_name(NULL, "siram");
+ if (!np2) {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "No siramproperty\n");
+ goto err_miss_si_property;
+ }
+ of_address_to_resource(np2, 0 , &res);
+ utdm_priv->siram = ioremap(res.start, res.end - res.start + 1);
+ of_node_put(np2);
+
+ if (siram_init_flag == 0) {
+ memset(utdm_priv->siram, 0, res.end - res.start + 1);
+ siram_init_flag = 1;
+ }
+
+ utdm_priv->ut_info = ut_info;
+ set_si_param(utdm_priv);
+
+ sprintf(ucc_tdm_ops.name, "%s%d", "tdm_ucc_", ucc_num + 1);
+ memcpy(&utdm_priv->adap, &ucc_tdm_ops, sizeof(struct tdm_adapter));
+
+ tdm_set_adapdata(&utdm_priv->adap, utdm_priv);
+ utdm_priv->adap.parent = &pdev->dev;
+
+ init_waitqueue_head(&utdm_priv->tdm_queue);
+ utdm_priv->tdm_queue_flag = false;
+
+ ret = utdm_init(utdm_priv);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to init utdm\n");
+ goto err_utdm_init;
+ }
+
+ ret = tdm_add_adapter(&utdm_priv->adap);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to add adapter\n");
+ goto err_utdm_init;
+ }
+
+ spin_lock_init(&utdm_priv->tdmlock);
+
+#ifdef DEBUG
+ dump_priv(utdm_priv);
+ dump_ucc(utdm_priv);
+ dump_bds(utdm_priv);
+ mem_disp((u8 *)utdm_priv->si_regs, 0x20);
+#endif
+
+ return 0;
+
+err_utdm_init:
+ iounmap(utdm_priv->siram);
+err_miss_si_property:
+ iounmap(utdm_priv->si_regs);
+err_miss_property:
+ kfree(utdm_priv);
+err_alloc_priv:
+ return ret;
+
+}
+
+static int ucc_tdm_remove(struct platform_device *pdev)
+{
+ struct ucc_tdm_private *priv = dev_get_drvdata(&pdev->dev);
+
+ utdm_stop(&priv->adap);
+ utdm_memclean(priv);
+
+ if (priv->si_regs) {
+ iounmap(priv->si_regs);
+ priv->si_regs = NULL;
+ }
+
+ if (priv->siram) {
+ iounmap(priv->siram);
+ priv->siram = NULL;
+ }
+ kfree(priv);
+
+ dev_info(&pdev->dev, "UCC based tdm module removed\n");
+
+ return 0;
+}
+
+static const struct of_device_id fsl_ucc_tdm_of_match[] = {
+ {
+ .compatible = "fsl,ucc-tdm",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, fsl_ucc_tdm_of_match);
+
+static struct platform_driver ucc_tdm_driver = {
+ .probe = ucc_tdm_probe,
+ .remove = ucc_tdm_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME,
+ .of_match_table = fsl_ucc_tdm_of_match,
+ },
+};
+
+static int __init ucc_tdm_init(void)
+{
+ return platform_driver_register(&ucc_tdm_driver);
+}
+
+static void __exit ucc_tdm_exit(void)
+{
+ platform_driver_unregister(&ucc_tdm_driver);
+}
+
+module_init(ucc_tdm_init);
+module_exit(ucc_tdm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Freescale Semiconductor Inc.");
+MODULE_DESCRIPTION("Driver For Freescale QE UCC TDM controller");
+MODULE_VERSION("1.0");
diff --git a/drivers/tdm/device/fsl_ucc_tdm.h b/drivers/tdm/device/fsl_ucc_tdm.h
new file mode 100644
index 0000000..e15c0f2
--- /dev/null
+++ b/drivers/tdm/device/fsl_ucc_tdm.h
@@ -0,0 +1,165 @@
+/*
+ * Freescale QUICC Engine TDM Device Driver
+ *
+ * Copyright 2011-2012 Freescale Semiconductor, Inc.
+ *
+ * Author: Haiying Wang <Haiying.Wang@freescale.com>
+ * Kai Jiang <Kai.Jiang@freescale.com>
+ *
+ * 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.
+ *
+ * This driver adds support for TDM devices via Freescale's QUICC Engine.
+ */
+
+
+#ifndef CONFIG_UCC_TDM_H
+#define CONFIG_UCC_TDM_H
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include <asm/ucc.h>
+#include <asm/ucc_fast.h>
+
+/* SI RAM entries */
+#define SIR_LAST 0x0001
+#define SIR_BYTE 0x0002
+#define SIR_CNT(x) ((x) << 2)
+#define SIR_CSEL(x) ((x) << 5)
+#define SIR_SGS 0x0200
+#define SIR_SWTR 0x4000
+#define SIR_MCC 0x8000
+#define SIR_IDLE 0
+
+/* SIxMR fields */
+#define SIMR_SAD(x) ((x) << 12)
+#define SIMR_SDM_NORMAL 0x0000
+#define SIMR_SDM_INTERNAL_LOOPBACK 0x0800
+#define SIMR_SDM_MASK 0x0c00
+#define SIMR_CRT 0x0040
+#define SIMR_SL 0x0020
+#define SIMR_CE 0x0010
+#define SIMR_FE 0x0008
+#define SIMR_GM 0x0004
+#define SIMR_TFSD(n) (n)
+#define SIMR_RFSD(n) ((n) << 8)
+
+enum tdm_ts_t {
+ TDM_TX_TS,
+ TDM_RX_TS
+};
+
+
+enum tdm_framer_t {
+ TDM_FRAMER_T1,
+ TDM_FRAMER_E1
+};
+
+enum tdm_mode_t {
+ TDM_INTERNAL_LOOPBACK,
+ TDM_NORMAL
+};
+
+struct ucc_transparent_param {
+ __be16 riptr;
+ __be16 tiptr;
+ __be16 res0;
+ __be16 mrblr;
+ __be32 rstate;
+ __be32 rbase;
+ __be16 rbdstat;
+ __be16 rbdlen;
+ __be32 rdptr;
+ __be32 tstate;
+ __be32 tbase;
+ __be16 tbdstat;
+ __be16 tbdlen;
+ __be32 tdptr;
+ __be32 rbptr;
+ __be32 tbptr;
+ __be32 rcrc;
+ __be32 res1;
+ __be32 tcrc;
+ __be32 res2;
+ __be32 res3;
+ __be32 c_mask;
+ __be32 c_pres;
+ __be16 disfc;
+ __be16 crcec;
+ __be32 res4[4];
+ __be16 ts_tmp;
+ __be16 tmp_mb;
+} __attribute__ ((__packed__));
+
+struct si_mode_info {
+ u8 simr_rfsd;
+ u8 simr_tfsd;
+ u8 simr_crt;
+ u8 simr_sl;
+ u8 simr_ce;
+ u8 simr_fe;
+ u8 simr_gm;
+};
+
+struct ucc_tdm_info {
+ struct ucc_fast_info uf_info;
+ struct si_mode_info si_info;
+};
+
+struct ucc_tdm_private {
+ struct ucc_tdm_info *ut_info;
+ struct ucc_fast_private *uccf;
+ struct device *dev;
+ struct ucc_fast __iomem *uf_regs; /* UCC Fast registers */
+ struct si1 __iomem *si_regs;
+ struct ucc_transparent_param __iomem *ucc_pram;
+ u16 tdm_port; /* port for this tdm:TDMA,TDMB,TDMC,TDMD */
+ u32 siram_entry_id;
+ u16 __iomem *siram;
+ enum tdm_mode_t tdm_mode;
+ enum tdm_framer_t tdm_framer_type;
+ bool tdm_busy;
+ u8 num_of_ts; /* the number of timeslots in this tdm frame */
+ u32 tx_ts_mask; /* tx time slot mask */
+ u32 rx_ts_mask; /*rx time slot mask */
+ u8 *rx_buffer; /* buffer used for Rx by the tdm */
+ u8 *tx_buffer; /* buffer used for Tx by the tdm */
+ dma_addr_t dma_rx_addr; /* dma mapped buffer for TDM Rx */
+ dma_addr_t dma_tx_addr; /* dma mapped buffer for TDM Tx */
+ struct qe_bd *tx_bd;
+ struct qe_bd *rx_bd;
+ u8 phase_rx;
+ u8 phase_tx;
+ u32 ucc_pram_offset;
+ u32 tx_bd_offset;
+ u32 rx_bd_offset;
+ spinlock_t tdmlock;
+ wait_queue_head_t tdm_queue;
+ bool tdm_queue_flag;
+ struct tdm_adapter adap;
+};
+
+#define NUM_OF_BUF 4
+#define MAX_RX_BUF_LENGTH (72*0x20)
+#define ALIGNMENT_OF_UCC_TRANS_PRAM 64
+#define SI_BANK_SIZE 128
+#define MAX_TDM_NUM 8
+#define BD_LEN_MASK 0xffff
+
+#endif