2019-05-27 09:55:05 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2010-03-11 18:32:21 +03:00
/*
* DaVinci Voice Codec Core Interface for TI platforms
*
* Copyright ( C ) 2010 Texas Instruments , Inc
*
* Author : Miguel Aguilar < miguel . aguilar @ ridgerun . com >
*/
# include <linux/init.h>
# include <linux/module.h>
# include <linux/device.h>
2010-03-29 21:52:40 +04:00
# include <linux/slab.h>
2010-03-11 18:32:21 +03:00
# include <linux/delay.h>
# include <linux/io.h>
# include <linux/clk.h>
2013-08-31 17:08:56 +04:00
# include <linux/regmap.h>
2010-03-11 18:32:21 +03:00
# include <sound/pcm.h>
# include <linux/mfd/davinci_voicecodec.h>
2015-01-05 12:01:23 +03:00
static const struct regmap_config davinci_vc_regmap = {
2013-08-31 17:08:56 +04:00
. reg_bits = 32 ,
. val_bits = 32 ,
} ;
2010-03-11 18:32:21 +03:00
static int __init davinci_vc_probe ( struct platform_device * pdev )
{
struct davinci_vc * davinci_vc ;
2013-06-18 14:05:40 +04:00
struct resource * res ;
2010-03-11 18:32:21 +03:00
struct mfd_cell * cell = NULL ;
2019-07-22 14:47:13 +03:00
dma_addr_t fifo_base ;
2010-03-11 18:32:21 +03:00
int ret ;
2013-05-23 19:25:11 +04:00
davinci_vc = devm_kzalloc ( & pdev - > dev ,
sizeof ( struct davinci_vc ) , GFP_KERNEL ) ;
2015-10-28 19:54:29 +03:00
if ( ! davinci_vc )
2010-03-11 18:32:21 +03:00
return - ENOMEM ;
2013-06-18 14:05:40 +04:00
davinci_vc - > clk = devm_clk_get ( & pdev - > dev , NULL ) ;
2010-03-11 18:32:21 +03:00
if ( IS_ERR ( davinci_vc - > clk ) ) {
dev_dbg ( & pdev - > dev ,
" could not get the clock for voice codec \n " ) ;
2013-05-23 19:25:11 +04:00
return - ENODEV ;
2010-03-11 18:32:21 +03:00
}
clk_enable ( davinci_vc - > clk ) ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2019-07-22 14:47:13 +03:00
fifo_base = ( dma_addr_t ) res - > start ;
2013-06-18 14:05:40 +04:00
davinci_vc - > base = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( davinci_vc - > base ) ) {
ret = PTR_ERR ( davinci_vc - > base ) ;
goto fail ;
2010-03-11 18:32:21 +03:00
}
2013-08-31 17:08:56 +04:00
davinci_vc - > regmap = devm_regmap_init_mmio ( & pdev - > dev ,
davinci_vc - > base ,
& davinci_vc_regmap ) ;
if ( IS_ERR ( davinci_vc - > regmap ) ) {
ret = PTR_ERR ( davinci_vc - > regmap ) ;
goto fail ;
}
2010-03-11 18:32:21 +03:00
res = platform_get_resource ( pdev , IORESOURCE_DMA , 0 ) ;
if ( ! res ) {
dev_err ( & pdev - > dev , " no DMA resource \n " ) ;
2010-06-01 18:34:38 +04:00
ret = - ENXIO ;
2013-06-18 14:05:40 +04:00
goto fail ;
2010-03-11 18:32:21 +03:00
}
davinci_vc - > davinci_vcif . dma_tx_channel = res - > start ;
2019-07-22 14:47:13 +03:00
davinci_vc - > davinci_vcif . dma_tx_addr = fifo_base + DAVINCI_VC_WFIFO ;
2010-03-11 18:32:21 +03:00
res = platform_get_resource ( pdev , IORESOURCE_DMA , 1 ) ;
if ( ! res ) {
dev_err ( & pdev - > dev , " no DMA resource \n " ) ;
2010-06-01 18:34:38 +04:00
ret = - ENXIO ;
2013-06-18 14:05:40 +04:00
goto fail ;
2010-03-11 18:32:21 +03:00
}
davinci_vc - > davinci_vcif . dma_rx_channel = res - > start ;
2019-07-22 14:47:13 +03:00
davinci_vc - > davinci_vcif . dma_rx_addr = fifo_base + DAVINCI_VC_RFIFO ;
2010-03-11 18:32:21 +03:00
davinci_vc - > dev = & pdev - > dev ;
davinci_vc - > pdev = pdev ;
/* Voice codec interface client */
cell = & davinci_vc - > cells [ DAVINCI_VC_VCIF_CELL ] ;
2011-01-27 16:28:36 +03:00
cell - > name = " davinci-vcif " ;
2011-04-06 18:39:45 +04:00
cell - > platform_data = davinci_vc ;
cell - > pdata_size = sizeof ( * davinci_vc ) ;
2010-03-11 18:32:21 +03:00
/* Voice codec CQ93VC client */
cell = & davinci_vc - > cells [ DAVINCI_VC_CQ93VC_CELL ] ;
2011-01-27 16:28:36 +03:00
cell - > name = " cq93vc-codec " ;
2011-04-06 18:39:45 +04:00
cell - > platform_data = davinci_vc ;
cell - > pdata_size = sizeof ( * davinci_vc ) ;
2010-03-11 18:32:21 +03:00
ret = mfd_add_devices ( & pdev - > dev , pdev - > id , davinci_vc - > cells ,
2012-09-11 11:16:36 +04:00
DAVINCI_VC_CELLS , NULL , 0 , NULL ) ;
2010-03-11 18:32:21 +03:00
if ( ret ! = 0 ) {
dev_err ( & pdev - > dev , " fail to register client devices \n " ) ;
2013-06-18 14:05:40 +04:00
goto fail ;
2010-03-11 18:32:21 +03:00
}
return 0 ;
2013-06-18 14:05:40 +04:00
fail :
2010-03-11 18:32:21 +03:00
clk_disable ( davinci_vc - > clk ) ;
return ret ;
}
2012-11-19 22:26:01 +04:00
static int davinci_vc_remove ( struct platform_device * pdev )
2010-03-11 18:32:21 +03:00
{
struct davinci_vc * davinci_vc = platform_get_drvdata ( pdev ) ;
mfd_remove_devices ( & pdev - > dev ) ;
clk_disable ( davinci_vc - > clk ) ;
return 0 ;
}
static struct platform_driver davinci_vc_driver = {
. driver = {
. name = " davinci_voicecodec " ,
} ,
2012-11-19 22:20:24 +04:00
. remove = davinci_vc_remove ,
2010-03-11 18:32:21 +03:00
} ;
2013-03-05 08:48:28 +04:00
module_platform_driver_probe ( davinci_vc_driver , davinci_vc_probe ) ;
2010-03-11 18:32:21 +03:00
MODULE_AUTHOR ( " Miguel Aguilar " ) ;
MODULE_DESCRIPTION ( " Texas Instruments DaVinci Voice Codec Core Interface " ) ;
MODULE_LICENSE ( " GPL " ) ;