2008-11-19 09:37:32 +03:00
/*
* ASoC driver for Lyrtech SFFSDR board .
*
* Author : Hugo Villeneuve
* Copyright ( C ) 2008 Lyrtech inc
*
* Based on ASoC driver for TI DAVINCI EVM platform , original copyright follow :
* Copyright : ( C ) 2007 MontaVista Software , Inc . , < source @ mvista . com >
*
* 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 .
*/
# include <linux/module.h>
# include <linux/moduleparam.h>
# include <linux/timer.h>
# include <linux/interrupt.h>
# include <linux/platform_device.h>
# include <linux/gpio.h>
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/soc.h>
# include <asm/dma.h>
2009-01-05 13:08:30 +03:00
# include <asm/mach-types.h>
2009-01-15 23:40:35 +03:00
# ifdef CONFIG_SFFSDR_FPGA
2008-11-19 09:37:32 +03:00
# include <asm/plat-sffsdr/sffsdr-fpga.h>
2009-01-15 23:40:35 +03:00
# endif
2008-11-19 09:37:32 +03:00
# include <mach/edma.h>
# include "../codecs/pcm3008.h"
# include "davinci-pcm.h"
# include "davinci-i2s.h"
2009-03-10 06:32:07 +03:00
/*
* CLKX and CLKR are the inputs for the Sample Rate Generator .
* FSX and FSR are outputs , driven by the sample Rate Generator .
*/
# define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
SND_SOC_DAIFMT_CBM_CFS | \
SND_SOC_DAIFMT_IB_NF )
2008-11-19 09:37:32 +03:00
static int sffsdr_hw_params ( struct snd_pcm_substream * substream ,
2009-03-10 06:32:08 +03:00
struct snd_pcm_hw_params * params )
2008-11-19 09:37:32 +03:00
{
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
2010-03-17 23:15:21 +03:00
struct snd_soc_dai * cpu_dai = rtd - > cpu_dai ;
2008-11-19 09:37:32 +03:00
int fs ;
int ret = 0 ;
2009-01-15 23:40:35 +03:00
/* Fsref can be 32000, 44100 or 48000. */
fs = params_rate ( params ) ;
# ifndef CONFIG_SFFSDR_FPGA
/* Without the FPGA module, the Fs is fixed at 44100 Hz */
if ( fs ! = 44100 ) {
pr_debug ( " warning: only 44.1 kHz is supported without SFFSDR FPGA module \n " ) ;
return - EINVAL ;
}
# endif
2009-03-10 06:32:07 +03:00
/* set cpu DAI configuration */
ret = snd_soc_dai_set_fmt ( cpu_dai , AUDIO_FORMAT ) ;
2008-11-19 09:37:32 +03:00
if ( ret < 0 )
return ret ;
pr_debug ( " sffsdr_hw_params: rate = %d Hz \n " , fs ) ;
2009-01-15 23:40:35 +03:00
# ifndef CONFIG_SFFSDR_FPGA
return 0 ;
# else
2008-11-19 09:37:32 +03:00
return sffsdr_fpga_set_codec_fs ( fs ) ;
2009-01-15 23:40:35 +03:00
# endif
2008-11-19 09:37:32 +03:00
}
static struct snd_soc_ops sffsdr_ops = {
. hw_params = sffsdr_hw_params ,
} ;
/* davinci-sffsdr digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link sffsdr_dai = {
. name = " PCM3008 " , /* Codec name */
. stream_name = " PCM3008 HiFi " ,
ASoC: davinci: fixes for multi-component
Multi-component commit f0fba2ad broke a few things which this patch should
fix. Tested on the DM355 EVM. I've been as careful as I can, but it would be
good if those with access to other Davinci boards could test.
--
The multi-component commit put the initialisation of
snd_soc_dai.[capture|playback]_dma_data into snd_soc_dai_ops.hw_params of the
McBSP, McASP & VCIF drivers (davinci-i2s.c, davinci-mcasp.c & davinci-vcif.c).
The initialisation had to be moved from the probe function in these drivers
because davinci_*_dai changed from snd_soc_dai to snd_soc_dai_driver.
Unfortunately, the DMA params pointer is needed by davinci_pcm_open (in
davinci-pcm.c) before hw_params is called. I have moved the initialisation to
a new snd_soc_dai_ops.startup function in each of these drivers. This fix
indicates that all platforms that use davinci-pcm must have been broken and
need to test with this fix.
--
The multi-component commit also changed the McBSP driver name from
"davinci-asp" to "davinci-i2s" in davinci-i2s.c without updating the board
level references to the driver name. This change is understandable, as there
is a similarly named "davinci-mcasp" driver in davinci-mcasp.c.
There is probably no 'correct' name for this driver. The DM6446 datasheet
calls it the "ASP" and describes it as a "specialised McBSP". The DM355
datasheet calls it the "ASP" and describes it as a "specialised ASP". The
DM365 datasheet calls it the "McBSP". Rather than fix this problem by
reverting to "davinci-asp", I've elected to avoid future confusion with the
"davinci-mcasp" driver by changing it to "davinci-mcbsp", which is also
consistent with the names of the functions in the driver. There are other
fixes required, so it was never going to be as simple as a revert anyway.
--
The DM365 only has one McBSP port (of the McBSP platforms, only the DM355 has
2 ports), so I've changed the the id of the platform_device from 0 to -1.
--
In davinci-evm.c, the DM6446 EVM can no longer share a snd_soc_dai_link
structure with the DM355 EVM as they use different cpu DAI names (the DM355
has 2 ports and the EVM uses the second port, but the DM6446 only has 1 port).
This also means that the 2 boards need different snd_soc_card structures.
--
The codec_name entries in davinci-evm.c didn't match the i2c ids in the board
files. I have only checked and fixed the details of the names used for the
McBSP based platforms. Someone with a McASP based platform (eg DA8xx) should
check the others.
Signed-off-by: Chris Paulson-Ellis <chris@edesix.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2010-11-16 15:27:09 +03:00
. cpu_dai_name = " davinci-mcbsp " ,
2010-03-17 23:15:21 +03:00
. codec_dai_name = " pcm3008-hifi " ,
. codec_name = " pcm3008-codec " ,
. platform_name = " davinci-pcm-audio " ,
2008-11-19 09:37:32 +03:00
. ops = & sffsdr_ops ,
} ;
/* davinci-sffsdr audio machine driver */
2008-11-18 23:50:34 +03:00
static struct snd_soc_card snd_soc_sffsdr = {
2008-11-19 09:37:32 +03:00
. name = " DaVinci SFFSDR " ,
. dai_link = & sffsdr_dai ,
. num_links = 1 ,
} ;
/* sffsdr audio private data */
static struct pcm3008_setup_data sffsdr_pcm3008_setup = {
. dem0_pin = GPIO ( 45 ) ,
. dem1_pin = GPIO ( 46 ) ,
. pdad_pin = GPIO ( 47 ) ,
. pdda_pin = GPIO ( 38 ) ,
} ;
2010-03-17 23:15:21 +03:00
struct platform_device pcm3008_codec = {
. name = " pcm3008-codec " ,
. id = 0 ,
. dev = {
. platform_data = & sffsdr_pcm3008_setup ,
} ,
2008-11-19 09:37:32 +03:00
} ;
static struct resource sffsdr_snd_resources [ ] = {
{
. start = DAVINCI_MCBSP_BASE ,
. end = DAVINCI_MCBSP_BASE + SZ_8K - 1 ,
. flags = IORESOURCE_MEM ,
} ,
} ;
static struct evm_snd_platform_data sffsdr_snd_data = {
. tx_dma_ch = DAVINCI_DMA_MCBSP_TX ,
. rx_dma_ch = DAVINCI_DMA_MCBSP_RX ,
} ;
static struct platform_device * sffsdr_snd_device ;
static int __init sffsdr_init ( void )
{
int ret ;
2009-01-05 13:08:30 +03:00
if ( ! machine_is_sffsdr ( ) )
return - EINVAL ;
2010-03-17 23:15:21 +03:00
platform_device_register ( & pcm3008_codec ) ;
2008-11-19 09:37:32 +03:00
sffsdr_snd_device = platform_device_alloc ( " soc-audio " , 0 ) ;
if ( ! sffsdr_snd_device ) {
printk ( KERN_ERR " platform device allocation failed \n " ) ;
return - ENOMEM ;
}
2010-03-17 23:15:21 +03:00
platform_set_drvdata ( sffsdr_snd_device , & snd_soc_sffsdr ) ;
2009-02-13 22:36:37 +03:00
platform_device_add_data ( sffsdr_snd_device , & sffsdr_snd_data ,
sizeof ( sffsdr_snd_data ) ) ;
2008-11-19 09:37:32 +03:00
ret = platform_device_add_resources ( sffsdr_snd_device ,
sffsdr_snd_resources ,
ARRAY_SIZE ( sffsdr_snd_resources ) ) ;
if ( ret ) {
2010-10-16 17:19:20 +04:00
printk ( KERN_ERR " platform device add resources failed \n " ) ;
2008-11-19 09:37:32 +03:00
goto error ;
}
ret = platform_device_add ( sffsdr_snd_device ) ;
if ( ret )
goto error ;
return ret ;
error :
platform_device_put ( sffsdr_snd_device ) ;
return ret ;
}
static void __exit sffsdr_exit ( void )
{
platform_device_unregister ( sffsdr_snd_device ) ;
2010-03-17 23:15:21 +03:00
platform_device_unregister ( & pcm3008_codec ) ;
2008-11-19 09:37:32 +03:00
}
module_init ( sffsdr_init ) ;
module_exit ( sffsdr_exit ) ;
MODULE_AUTHOR ( " Hugo Villeneuve " ) ;
MODULE_DESCRIPTION ( " Lyrtech SFFSDR ASoC driver " ) ;
MODULE_LICENSE ( " GPL " ) ;