/* * Requests a dma transfer */ int request_dma_chain(struct dma_chain *chain_params) { int error; chain_params->finished = 0; /* Configure the dma channel parameters for the chain*/ chain_params->channel_params.data_type = chain_params->data_type; chain_params->channel_params.elem_count = 0; chain_params->channel_params.frame_count = 1; chain_params->channel_params.src_amode = chain_params->addressing_mode; chain_params->channel_params.src_start = 0; chain_params->channel_params.src_ei = 0; chain_params->channel_params.src_fi = 0; chain_params->channel_params.dst_amode = chain_params->addressing_mode; chain_params->channel_params.dst_start = 0; chain_params->channel_params.dst_ei = 0; chain_params->channel_params.dst_fi = 0; chain_params->channel_params.trigger = chain_params->device_id; chain_params->channel_params.sync_mode = chain_params->sync_mode; chain_params->channel_params.ie = 0; chain_params->channel_params.burst_mode = chain_params->data_burst; /* Request the chain */ printk(KERN_DEBUG "Requesting OMAP DMA chain transfer\n"); error = omap_request_dma_chain(chain_params->device_id, "dma_test", dma_callback_chain, &(chain_params->chain_id), chain_params->channel_count, chain_params->chain_type, chain_params->channel_params); if (error) { printk(KERN_ERR "Request failed\n"); chain_params->request_success = 0; return 1; } chain_params->request_success = 1; return 0; }
int omap2_mcbsp_dma_trans_params(unsigned int id, struct omap_mcbsp_dma_transfer_params *tp) { struct omap_mcbsp *mcbsp; struct omap_dma_channel_params tx_params; int err = 0, chain_id = -1; void __iomem *io_base; u32 dt = 0; if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } mcbsp = id_to_mcbsp_ptr(id); io_base = mcbsp->io_base; dt = tp->word_length1; if ((dt != OMAP_MCBSP_WORD_8) && (dt != OMAP_MCBSP_WORD_16) && (dt != OMAP_MCBSP_WORD_32)) return -EINVAL; if (dt == OMAP_MCBSP_WORD_8) tx_params.data_type = OMAP_DMA_DATA_TYPE_S8; else if (dt == OMAP_MCBSP_WORD_16) tx_params.data_type = OMAP_DMA_DATA_TYPE_S16; else if (dt == OMAP_MCBSP_WORD_32) tx_params.data_type = OMAP_DMA_DATA_TYPE_S32; else return -EINVAL; tx_params.read_prio = DMA_CH_PRIO_HIGH; tx_params.write_prio = DMA_CH_PRIO_HIGH; tx_params.sync_mode = OMAP_DMA_SYNC_ELEMENT; tx_params.dst_fi = 0; tx_params.trigger = mcbsp->dma_tx_sync; tx_params.src_or_dst_synch = 0; tx_params.dst_amode = OMAP_DMA_AMODE_CONSTANT; tx_params.dst_ei = 0; /* Indexing is always in bytes - so multiply with dt */ mcbsp->tx_word_length = tx_params.data_type << 0x1; if (tx_params.data_type == 0) mcbsp->tx_word_length = 1; dt = mcbsp->tx_word_length; /* SKIP_FIRST and SKIP_SECOND- skip alternate data in 24 bit mono */ if (tp->skip_alt == OMAP_MCBSP_SKIP_SECOND) { tx_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX; tx_params.src_ei = (1); tx_params.src_fi = (1) + ((-1) * dt); } else if (tp->skip_alt == OMAP_MCBSP_SKIP_FIRST) { tx_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX; tx_params.src_ei = 1 + (-2) * dt; tx_params.src_fi = 1 + (2) * dt; } else { tx_params.src_amode = OMAP_DMA_AMODE_POST_INC; tx_params.src_ei = 0; tx_params.src_fi = 0; } mcbsp->txskip_alt = tp->skip_alt; mcbsp->auto_reset &= ~OMAP_MCBSP_AUTO_XRST; mcbsp->auto_reset |= (tp->auto_reset & OMAP_MCBSP_AUTO_XRST); mcbsp->tx_callback = tp->callback; /* Based on Rjust we can do double indexing DMA params configuration */ if (mcbsp->dma_tx_lch == -1) { err = omap_request_dma_chain(id, "McBSP TX", omap2_mcbsp_tx_dma_callback, &chain_id, 2, OMAP_DMA_DYNAMIC_CHAIN, tx_params); if (err < 0) { printk(KERN_ERR "Transmit path configuration failed \n"); return -EINVAL; } mcbsp->tx_dma_chain_state = 0; mcbsp->dma_tx_lch = chain_id; } else { /* DMA params already set, modify the same!! */ err = omap_modify_dma_chain_params(mcbsp->dma_tx_lch, tx_params); if (err < 0) return -EINVAL; } return 0; }
/* * Configure the receiver parameters * id : McBSP Interface ID * rp : DMA Receive parameters */ int omap2_mcbsp_dma_recv_params(unsigned int id, struct omap_mcbsp_dma_transfer_params *rp) { struct omap_mcbsp *mcbsp; void __iomem *io_base; int err, chain_id = -1; struct omap_dma_channel_params rx_params; u32 dt = 0; if (!omap_mcbsp_check_valid_id(id)) { printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return -ENODEV; } mcbsp = id_to_mcbsp_ptr(id); io_base = mcbsp->io_base; dt = rp->word_length1; if (dt == OMAP_MCBSP_WORD_8) rx_params.data_type = OMAP_DMA_DATA_TYPE_S8; else if (dt == OMAP_MCBSP_WORD_16) rx_params.data_type = OMAP_DMA_DATA_TYPE_S16; else if (dt == OMAP_MCBSP_WORD_32) rx_params.data_type = OMAP_DMA_DATA_TYPE_S32; else return -EINVAL; rx_params.read_prio = DMA_CH_PRIO_HIGH; rx_params.write_prio = DMA_CH_PRIO_HIGH; rx_params.sync_mode = OMAP_DMA_SYNC_ELEMENT; rx_params.src_fi = 0; rx_params.trigger = mcbsp->dma_rx_sync; rx_params.src_or_dst_synch = 0x01; rx_params.src_amode = OMAP_DMA_AMODE_CONSTANT; rx_params.src_ei = 0x0; /* Indexing is always in bytes - so multiply with dt */ dt = (rx_params.data_type == OMAP_DMA_DATA_TYPE_S8) ? 1 : (rx_params.data_type == OMAP_DMA_DATA_TYPE_S16) ? 2 : 4; /* SKIP_FIRST and SKIP_SECOND- skip alternate data in 24 bit mono */ if (rp->skip_alt == OMAP_MCBSP_SKIP_SECOND) { rx_params.dst_amode = OMAP_DMA_AMODE_DOUBLE_IDX; rx_params.dst_ei = (1); rx_params.dst_fi = (1) + ((-1) * dt); } else if (rp->skip_alt == OMAP_MCBSP_SKIP_FIRST) { rx_params.dst_amode = OMAP_DMA_AMODE_DOUBLE_IDX; rx_params.dst_ei = 1 + (-2) * dt; rx_params.dst_fi = 1 + (2) * dt; } else { rx_params.dst_amode = OMAP_DMA_AMODE_POST_INC; rx_params.dst_ei = 0; rx_params.dst_fi = 0; } mcbsp->rxskip_alt = rp->skip_alt; mcbsp->auto_reset &= ~OMAP_MCBSP_AUTO_RRST; mcbsp->auto_reset |= (rp->auto_reset & OMAP_MCBSP_AUTO_RRST); mcbsp->rx_word_length = rx_params.data_type << 0x1; if (rx_params.data_type == 0) mcbsp->rx_word_length = 1; mcbsp->rx_callback = rp->callback; /* request for a chain of dma channels for data reception */ if (mcbsp->dma_rx_lch == -1) { err = omap_request_dma_chain(id, "McBSP RX", omap2_mcbsp_rx_dma_callback, &chain_id, 2, OMAP_DMA_DYNAMIC_CHAIN, rx_params); if (err < 0) { printk(KERN_ERR "Receive path configuration failed \n"); return -EINVAL; } mcbsp->dma_rx_lch = chain_id; mcbsp->rx_dma_chain_state = 0; } else { /* DMA params already set, modify the same!! */ err = omap_modify_dma_chain_params(mcbsp->dma_rx_lch, rx_params); if (err < 0) return -EINVAL; } return 0; }