2008-07-03 13:24:40 +04:00
/*
* linux / arch / arm / mach - omap1 / mcbsp . c
*
* Copyright ( C ) 2008 Instituto Nokia de Tecnologia
* Contact : Eduardo Valentin < eduardo . valentin @ indt . org . br >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* Multichannel mode not supported .
*/
# include <linux/module.h>
# include <linux/init.h>
# include <linux/clk.h>
# include <linux/err.h>
# include <linux/io.h>
# include <linux/platform_device.h>
2009-01-15 14:09:51 +03:00
# include <mach/irqs.h>
2009-10-20 20:40:47 +04:00
# include <plat/dma.h>
# include <plat/mux.h>
# include <plat/cpu.h>
# include <plat/mcbsp.h>
# include <plat/dsp_common.h>
2008-07-03 13:24:40 +04:00
# define DPS_RSTCT2_PER_EN (1 << 0)
# define DSP_RSTCT2_WD_PER_EN (1 << 1)
2009-01-23 13:26:46 +03:00
static int dsp_use ;
static struct clk * api_clk ;
static struct clk * dsp_clk ;
2008-07-03 13:24:40 +04:00
static void omap1_mcbsp_request ( unsigned int id )
{
/*
* On 1510 , 1610 and 1710 , McBSP1 and McBSP3
* are DSP public peripherals .
*/
if ( id = = OMAP_MCBSP1 | | id = = OMAP_MCBSP3 ) {
2009-01-23 13:26:46 +03:00
if ( dsp_use + + = = 0 ) {
2009-04-24 07:11:07 +04:00
api_clk = clk_get ( NULL , " api_ck " ) ;
dsp_clk = clk_get ( NULL , " dsp_ck " ) ;
2009-01-23 13:26:46 +03:00
if ( ! IS_ERR ( api_clk ) & & ! IS_ERR ( dsp_clk ) ) {
clk_enable ( api_clk ) ;
clk_enable ( dsp_clk ) ;
omap_dsp_request_mem ( ) ;
/*
* DSP external peripheral reset
* FIXME : This should be moved to dsp code
*/
__raw_writew ( __raw_readw ( DSP_RSTCT2 ) | DPS_RSTCT2_PER_EN |
DSP_RSTCT2_WD_PER_EN , DSP_RSTCT2 ) ;
}
}
2008-07-03 13:24:40 +04:00
}
}
static void omap1_mcbsp_free ( unsigned int id )
{
2009-01-23 13:26:46 +03:00
if ( id = = OMAP_MCBSP1 | | id = = OMAP_MCBSP3 ) {
if ( - - dsp_use = = 0 ) {
omap_dsp_release_mem ( ) ;
if ( ! IS_ERR ( api_clk ) ) {
clk_disable ( api_clk ) ;
clk_put ( api_clk ) ;
}
if ( ! IS_ERR ( dsp_clk ) ) {
clk_disable ( dsp_clk ) ;
clk_put ( dsp_clk ) ;
}
}
}
2008-07-03 13:24:40 +04:00
}
static struct omap_mcbsp_ops omap1_mcbsp_ops = {
. request = omap1_mcbsp_request ,
. free = omap1_mcbsp_free ,
} ;
2009-09-22 09:49:35 +04:00
# if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
2009-09-22 13:02:58 +04:00
static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata [ ] = {
2008-07-03 13:24:40 +04:00
{
2009-09-22 13:02:58 +04:00
. phys_base = OMAP7XX_MCBSP1_BASE ,
2008-07-03 13:24:40 +04:00
. dma_rx_sync = OMAP_DMA_MCBSP1_RX ,
. dma_tx_sync = OMAP_DMA_MCBSP1_TX ,
2009-09-18 07:09:39 +04:00
. rx_irq = INT_7XX_McBSP1RX ,
. tx_irq = INT_7XX_McBSP1TX ,
2008-07-03 13:24:40 +04:00
. ops = & omap1_mcbsp_ops ,
} ,
{
2009-09-22 13:02:58 +04:00
. phys_base = OMAP7XX_MCBSP2_BASE ,
2008-07-03 13:24:40 +04:00
. dma_rx_sync = OMAP_DMA_MCBSP3_RX ,
. dma_tx_sync = OMAP_DMA_MCBSP3_TX ,
2009-09-18 07:09:39 +04:00
. rx_irq = INT_7XX_McBSP2RX ,
. tx_irq = INT_7XX_McBSP2TX ,
2008-07-03 13:24:40 +04:00
. ops = & omap1_mcbsp_ops ,
} ,
} ;
2009-09-22 13:02:58 +04:00
# define OMAP7XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap7xx_mcbsp_pdata)
2008-07-03 13:24:40 +04:00
# else
2009-09-22 13:02:58 +04:00
# define omap7xx_mcbsp_pdata NULL
# define OMAP7XX_MCBSP_PDATA_SZ 0
2008-07-03 13:24:40 +04:00
# endif
# ifdef CONFIG_ARCH_OMAP15XX
static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata [ ] = {
{
2008-09-04 02:46:18 +04:00
. phys_base = OMAP1510_MCBSP1_BASE ,
2008-07-03 13:24:40 +04:00
. dma_rx_sync = OMAP_DMA_MCBSP1_RX ,
. dma_tx_sync = OMAP_DMA_MCBSP1_TX ,
. rx_irq = INT_McBSP1RX ,
. tx_irq = INT_McBSP1TX ,
. ops = & omap1_mcbsp_ops ,
2009-01-29 19:57:12 +03:00
} ,
2008-07-03 13:24:40 +04:00
{
2008-09-04 02:46:18 +04:00
. phys_base = OMAP1510_MCBSP2_BASE ,
2008-07-03 13:24:40 +04:00
. dma_rx_sync = OMAP_DMA_MCBSP2_RX ,
. dma_tx_sync = OMAP_DMA_MCBSP2_TX ,
. rx_irq = INT_1510_SPI_RX ,
. tx_irq = INT_1510_SPI_TX ,
. ops = & omap1_mcbsp_ops ,
} ,
{
2008-09-04 02:46:18 +04:00
. phys_base = OMAP1510_MCBSP3_BASE ,
2008-07-03 13:24:40 +04:00
. dma_rx_sync = OMAP_DMA_MCBSP3_RX ,
. dma_tx_sync = OMAP_DMA_MCBSP3_TX ,
. rx_irq = INT_McBSP3RX ,
. tx_irq = INT_McBSP3TX ,
. ops = & omap1_mcbsp_ops ,
} ,
} ;
# define OMAP15XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap15xx_mcbsp_pdata)
# else
# define omap15xx_mcbsp_pdata NULL
# define OMAP15XX_MCBSP_PDATA_SZ 0
# endif
# ifdef CONFIG_ARCH_OMAP16XX
static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata [ ] = {
{
2008-09-04 02:46:18 +04:00
. phys_base = OMAP1610_MCBSP1_BASE ,
2008-07-03 13:24:40 +04:00
. dma_rx_sync = OMAP_DMA_MCBSP1_RX ,
. dma_tx_sync = OMAP_DMA_MCBSP1_TX ,
. rx_irq = INT_McBSP1RX ,
. tx_irq = INT_McBSP1TX ,
. ops = & omap1_mcbsp_ops ,
} ,
{
2008-09-04 02:46:18 +04:00
. phys_base = OMAP1610_MCBSP2_BASE ,
2008-07-03 13:24:40 +04:00
. dma_rx_sync = OMAP_DMA_MCBSP2_RX ,
. dma_tx_sync = OMAP_DMA_MCBSP2_TX ,
. rx_irq = INT_1610_McBSP2_RX ,
. tx_irq = INT_1610_McBSP2_TX ,
. ops = & omap1_mcbsp_ops ,
} ,
{
2008-09-04 02:46:18 +04:00
. phys_base = OMAP1610_MCBSP3_BASE ,
2008-07-03 13:24:40 +04:00
. dma_rx_sync = OMAP_DMA_MCBSP3_RX ,
. dma_tx_sync = OMAP_DMA_MCBSP3_TX ,
. rx_irq = INT_McBSP3RX ,
. tx_irq = INT_McBSP3TX ,
. ops = & omap1_mcbsp_ops ,
} ,
} ;
# define OMAP16XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap16xx_mcbsp_pdata)
# else
# define omap16xx_mcbsp_pdata NULL
# define OMAP16XX_MCBSP_PDATA_SZ 0
# endif
int __init omap1_mcbsp_init ( void )
{
2009-09-22 09:49:35 +04:00
if ( cpu_is_omap7xx ( ) )
2009-09-22 13:02:58 +04:00
omap_mcbsp_count = OMAP7XX_MCBSP_PDATA_SZ ;
2008-10-08 11:01:39 +04:00
if ( cpu_is_omap15xx ( ) )
omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ ;
if ( cpu_is_omap16xx ( ) )
omap_mcbsp_count = OMAP16XX_MCBSP_PDATA_SZ ;
mcbsp_ptr = kzalloc ( omap_mcbsp_count * sizeof ( struct omap_mcbsp * ) ,
GFP_KERNEL ) ;
if ( ! mcbsp_ptr )
return - ENOMEM ;
2009-09-22 09:49:35 +04:00
if ( cpu_is_omap7xx ( ) )
2009-09-22 13:02:58 +04:00
omap_mcbsp_register_board_cfg ( omap7xx_mcbsp_pdata ,
OMAP7XX_MCBSP_PDATA_SZ ) ;
2008-07-03 13:24:40 +04:00
if ( cpu_is_omap15xx ( ) )
omap_mcbsp_register_board_cfg ( omap15xx_mcbsp_pdata ,
OMAP15XX_MCBSP_PDATA_SZ ) ;
if ( cpu_is_omap16xx ( ) )
omap_mcbsp_register_board_cfg ( omap16xx_mcbsp_pdata ,
OMAP16XX_MCBSP_PDATA_SZ ) ;
return omap_mcbsp_init ( ) ;
}
arch_initcall ( omap1_mcbsp_init ) ;