diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 4ada6a9ca4aa..565b9064a328 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -126,6 +126,8 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) return -ENOMEM; } + pdata->mcbsp_config_type = oh->class->rev; + if (oh->class->rev == MCBSP_CONFIG_TYPE3) { if (id == 2) /* The FIFO has 1024 + 256 locations */ diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h index 964a940c475d..21c9b104c615 100644 --- a/arch/arm/plat-omap/include/plat/mcbsp.h +++ b/arch/arm/plat-omap/include/plat/mcbsp.h @@ -81,6 +81,8 @@ static struct platform_device omap_mcbsp##port_nr = { \ #define OMAP_MCBSP_REG_DRR1 0x02 #define OMAP_MCBSP_REG_DXR2 0x04 #define OMAP_MCBSP_REG_DXR1 0x06 +#define OMAP_MCBSP_REG_DRR 0x02 +#define OMAP_MCBSP_REG_DXR 0x06 #define OMAP_MCBSP_REG_SPCR2 0x08 #define OMAP_MCBSP_REG_SPCR1 0x0a #define OMAP_MCBSP_REG_RCR2 0x0c @@ -423,6 +425,7 @@ struct omap_mcbsp_platform_data { unsigned long phys_base_st; #endif u16 buffer_size; + unsigned int mcbsp_config_type; }; struct omap_mcbsp_st_data { @@ -473,6 +476,7 @@ struct omap_mcbsp { u16 max_rx_thres; #endif void *reg_cache; + unsigned int mcbsp_config_type; }; /** @@ -541,6 +545,9 @@ int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type); void omap2_mcbsp1_mux_clkr_src(u8 mux); void omap2_mcbsp1_mux_fsr_src(u8 mux); +int omap_mcbsp_dma_ch_params(unsigned int id, unsigned int stream); +int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream); + #ifdef CONFIG_ARCH_OMAP3 /* Sidetone specific API */ int omap_st_set_chgain(unsigned int id, int channel, s16 chgain); diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 6d230164b4f9..d598d9fd65ac 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -229,6 +229,69 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) } EXPORT_SYMBOL(omap_mcbsp_config); +/** + * omap_mcbsp_dma_params - returns the dma channel number + * @id - mcbsp id + * @stream - indicates the direction of data flow (rx or tx) + * + * Returns the dma channel number for the rx channel or tx channel + * based on the value of @stream for the requested mcbsp given by @id + */ +int omap_mcbsp_dma_ch_params(unsigned int id, unsigned int stream) +{ + struct omap_mcbsp *mcbsp; + + 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); + + if (stream) + return mcbsp->dma_rx_sync; + else + return mcbsp->dma_tx_sync; +} +EXPORT_SYMBOL(omap_mcbsp_dma_ch_params); + +/** + * omap_mcbsp_dma_reg_params - returns the address of mcbsp data register + * @id - mcbsp id + * @stream - indicates the direction of data flow (rx or tx) + * + * Returns the address of mcbsp data transmit register or data receive register + * to be used by DMA for transferring/receiving data based on the value of + * @stream for the requested mcbsp given by @id + */ +int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream) +{ + struct omap_mcbsp *mcbsp; + int data_reg; + + 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); + + data_reg = mcbsp->phys_dma_base; + + if (mcbsp->mcbsp_config_type < MCBSP_CONFIG_TYPE2) { + if (stream) + data_reg += OMAP_MCBSP_REG_DRR1; + else + data_reg += OMAP_MCBSP_REG_DXR1; + } else { + if (stream) + data_reg += OMAP_MCBSP_REG_DRR; + else + data_reg += OMAP_MCBSP_REG_DXR; + } + + return data_reg; +} +EXPORT_SYMBOL(omap_mcbsp_dma_reg_params); + #ifdef CONFIG_ARCH_OMAP3 static struct omap_device *find_omap_device_by_dev(struct device *dev) { @@ -1835,6 +1898,7 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) mcbsp->pdata = pdata; mcbsp->dev = &pdev->dev; mcbsp_ptr[id] = mcbsp; + mcbsp->mcbsp_config_type = pdata->mcbsp_config_type; platform_set_drvdata(pdev, mcbsp); pm_runtime_enable(mcbsp->dev);