/* * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. * * 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; version 2 of the License. * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ML7213IOH_PLAT_H #define ML7213IOH_PLAT_H #include #include #define I2SCLKCNT0_OFFSET 0x3000 #define I2SCLKCNT1_OFFSET 0x3010 #define I2SCLKCNT2_OFFSET 0x3020 #define I2SCLKCNT3_OFFSET 0x3030 #define I2SCLKCNT4_OFFSET 0x3040 #define I2SCLKCNT5_OFFSET 0x3050 #define I2SISTATUS_OFFSET 0x3080 #define I2SIDISP_OFFSET 0x3084 #define I2SIMASK_OFFSET 0x3088 #define I2SIMASKCLR_OFFSET 0x308C #define I2SSRST_OFFSET 0x3FFC #define I2SDRTX_OFFSET 0x0 #define I2SCNTTX_OFFSET 0x4 #define I2SFIFOCTX_OFFSET 0x8 #define I2SAFTX_OFFSET 0xC #define I2SAETX_OFFSET 0x10 #define I2SMSKTX_OFFSET 0x14 #define I2SISTTX_OFFSET 0x18 #define I2SMONTX_OFFSET 0x1C #define I2SDRRX_OFFSET 0x20 #define I2SCNTRX_OFFSET 0x24 #define I2SFIFOCRX_OFFSET 0x28 #define I2SAFRX_OFFSET 0x2C #define I2SAERX_OFFSET 0x30 #define I2SMSKRX_OFFSET 0x34 #define I2SISTRX_OFFSET 0x38 #define I2SMONRX_OFFSET 0x3C #define FIRST_TX_OFFSET 0x0 #define FIRST_RX_OFFSET 0x0 #define I2SDRTXMIRROR_OFFSET 0x100 #define I2SDRRXMIRROR_OFFSET 0x400 #define TX_OFFSET_INCREMENT 0x800 #define I2S_ALL_INTERRUPT_BITS 0x3F003F #define I2S_IDISP_BITS 0x3F003F #define I2S_IDISP_TX_BITS 0x00003F #define I2S_IDISP_RX_BITS 0x3F0000 #define TX_BIT_FIMSK 0x1 /*Fifo full interrupt mask bit*/ #define TX_BIT_AFIMSK 0x2 /*Fifo Almost full interrupt mask bit*/ #define TX_BIT_EIMSK 0x4 /*Fifo empty interrupt mask bit*/ #define TX_BIT_AEIMSK 0x8 /*Fifo Almost empty interrupt mask bit*/ #define TX_BIT_DMAMSK 0x10 /*Masks DMA*/ #define TX_BIT_DMATC 0x100 #define I2S_TX_ALL_INTR_MASK_BITS (TX_BIT_FIMSK | TX_BIT_AFIMSK | TX_BIT_EIMSK \ | TX_BIT_AEIMSK) #define I2S_TX_NORMAL_INTR_MASK_BITS (TX_BIT_FIMSK | TX_BIT_AFIMSK) #define RX_BIT_FIMSK 0x1 /*Fifo full interrupt mask bit*/ #define RX_BIT_AFIMSK 0x2 /*Fifo Almost full interrupt mask bit*/ #define RX_BIT_EIMSK 0x4 /*Fifo empty interrupt mask bit*/ #define RX_BIT_AEIMSK 0x8 /*Fifo Almost empty interrupt mask bit*/ #define RX_BIT_DMAMSK 0x10 /*Masks DMA*/ #define RX_BIT_DMATC 0x100 #define I2S_RX_ALL_INTR_MASK_BITS (RX_BIT_FIMSK | RX_BIT_AFIMSK | RX_BIT_EIMSK \ | RX_BIT_AEIMSK) #define I2S_RX_NORMAL_INTR_MASK_BITS (RX_BIT_EIMSK | RX_BIT_AEIMSK) #define I2S_TX_FINT 0x1 /*Full Interrupt*/ #define I2S_TX_AFINT 0x2 /*Almost full interrupt*/ #define I2S_TX_EINT 0x4 /*Empty interrupt*/ #define I2S_TX_AEINT 0x8 /*Almost empty interrupt*/ #define I2S_RX_FINT 0x1 /*Full Interrupt*/ #define I2S_RX_AFINT 0x2 /*Almost full interrupt*/ #define I2S_RX_EINT 0x4 /*Empty interrupt*/ #define I2S_RX_AEINT 0x8 /*Almost empty interrupt*/ #define I2S_FIFO_TX_FCLR BIT(0) #define I2S_FIFO_TX_RUN BIT(4) #define I2S_FIFO_RX_FCLR BIT(0) #define I2S_FIFO_RX_RUN BIT(4) #define FIFO_CTRL_BIT_TX_RUN 0x10 #define FIFO_CTRL_BIT_RX_RUN 0x10 #define I2S_CNT_BIT_TEL 0x1 #define I2S_IMASK_TX_BIT_START 0 #define I2S_IMASK_RX_BIT_START 16 #define MAX_I2S_IF MAX_I2S_CH /* DMA channel name configuration */ static struct ioh_dma_config { char rx_chan[8]; char tx_chan[8]; } ioh_dma_config[] = { { /* I2S0 */ .tx_chan = "i2s_tx0", .rx_chan = "i2s_rx0", }, { /* I2S1 */ .tx_chan = "i2s_tx1", .rx_chan = "i2s_rx1", }, { /* I2S2 */ .tx_chan = "i2s_tx2", .rx_chan = "i2s_rx2", }, { /* I2S3 */ .tx_chan = "i2s_tx3", .rx_chan = "i2s_rx3", }, { /* I2S4 */ .tx_chan = "i2s_tx4", .rx_chan = "i2s_rx4", }, { /* I2S5 */ .tx_chan = "i2s_tx5", .rx_chan = "i2s_rx5", }, }; struct ioh_i2s_data { struct device *dev; void *iobase; int ch; atomic_t rx_busy; atomic_t tx_busy; int ignore_rx_overrun; /* Transmit side DMA */ atomic_t pending_tx; struct ioh_dma_config *dma_config; char rx_name[16]; char tx_name[16]; struct scatterlist *sg_tx_p; struct scatterlist *sg_rx_p; struct scatterlist *sg_tx_cur; /* current head of tx sg */ struct scatterlist *sg_rx_cur; /* current head of tx sg */ int tx_num; /* The number of sent sg */ int rx_num; /* The number of sent sg */ void *rxbuf_virt; void *txbuf_virt; unsigned char *tx_tail; unsigned char *tx_head; unsigned char *tx_data_head; unsigned char *tx_complete; unsigned int tx_avail; unsigned char *rx_tail; unsigned char *rx_head; unsigned char *rx_data_head; unsigned char *rx_complete; unsigned int rx_avail; struct dma_chan *chan_tx; struct dma_chan *chan_rx; int rx_nent; /* The number of rx scatter list */ int tx_nent; /* The number of tx scatter list */ struct dma_async_tx_descriptor *desc_tx; struct dma_async_tx_descriptor *desc_rx; dma_addr_t tx_buf_dma; dma_addr_t rx_buf_dma; spinlock_t tx_lock; struct pch_dma_slave param_tx; struct pch_dma_slave param_rx; unsigned int mapbase; dma_addr_t tx_reg_addr[2]; void *rx_callback_data; void (*rx_done) (void *callback_data, int status, int num, int avail); void *tx_callback_data; void (*tx_done) (void *callback_data, int status, int num, int avail); unsigned int tx_lower_data_flag; int dma_tx_unit; /* 1Byte of 2Byte or 4Byte */ int dma_rx_unit; /* 1Byte of 2Byte or 4Byte */ int dma_tx_width; int dma_rx_width; int txexe_flag; int rxexe_flag; struct tasklet_struct tx_tasklet; struct tasklet_struct rx_tasklet; struct ioh_i2s_pm_ch_reg ch_reg_save; }; struct ioh_i2s_data_pci { struct ioh_i2s_data devs[MAX_I2S_IF]; void __iomem *membase; unsigned int mapbase; struct ioh_i2s_pm_common_reg cmn_reg_save; struct snd_card *card; struct device *dev; }; #endif