@ -24,111 +24,159 @@
# include <malloc.h>
# include <common.h>
# include <asm/io.h>
# include <libfdt.h>
# include <fdtdec.h>
# include <i2c.h>
# include <i2s.h>
# include <sound.h>
# include "wm8994.h"
# include <asm/arch/sound.h>
# include "wm8994.h"
/* defines */
# define SOUND_400_HZ 400
# define SOUND_BITS_IN_BYTE 8
static struct i2stx_info g_i2stx_pri ;
static struct sound_codec_info g_codec_info ;
/*
* get_sound_fdt_values gets fdt values for i2s parameters
* get_sound_i2s_values gets values for i2s parameters
*
* @ param i2stx_info i2s transmitter transfer param structure
* @ param blob FDT blob
*/
static void get_sound_i2s_values ( struct i2stx_info * i2s )
{
i2s - > base_address = samsung_get_base_i2s ( ) ;
i2s - > audio_pll_clk = I2S_PLL_CLK ;
i2s - > samplingrate = I2S_SAMPLING_RATE ;
i2s - > bitspersample = I2S_BITS_PER_SAMPLE ;
i2s - > channels = I2S_CHANNELS ;
i2s - > rfs = I2S_RFS ;
i2s - > bfs = I2S_BFS ;
}
/*
* Gets fdt values for wm8994 config parameters
*
* @ param pcodec_info codec information structure
* @ param blob FDT blob
* @ return int value , 0 for success
* @ param blob FDT blob if enabled else NULL
*/
static int get_sound_wm8994_values ( struct sound_codec_info * pcodec_info )
static int get_sound_i2s_values ( struct i2stx_info * i2s , const void * blob )
{
# ifdef CONFIG_OF_CONTROL
int node ;
int error = 0 ;
int base ;
switch ( AUDIO_COMPAT ) {
case AUDIO_COMPAT_SPI :
debug ( " %s: Support not added for SPI interface \n " , __func__ ) ;
node = fdtdec_next_compatible ( blob , 0 ,
COMPAT_SAMSUNG_EXYNOS5_SOUND ) ;
if ( node < = 0 ) {
debug ( " EXYNOS_SOUND: No node for sound in device tree \n " ) ;
return - 1 ;
break ;
case AUDIO_COMPAT_I2C :
pcodec_info - > i2c_bus = AUDIO_I2C_BUS ;
pcodec_info - > i2c_dev_addr = AUDIO_I2C_REG ;
debug ( " i2c dev addr = %d \n " , pcodec_info - > i2c_dev_addr ) ;
break ;
default :
debug ( " %s: Unknown compat id %d \n " , __func__ , AUDIO_COMPAT ) ;
}
/*
* Get the pre - defined sound specific values from FDT .
* All of these are expected to be correct otherwise
* wrong register values in i2s setup parameters
* may result in no sound play .
*/
base = fdtdec_get_addr ( blob , node , " reg " ) ;
if ( base = = FDT_ADDR_T_NONE ) {
debug ( " %s: Missing i2s base \n " , __func__ ) ;
return - 1 ;
}
i2s - > base_address = base ;
i2s - > audio_pll_clk = fdtdec_get_int ( blob ,
node , " samsung,i2s-epll-clock-frequency " , - 1 ) ;
error | = i2s - > audio_pll_clk ;
debug ( " audio_pll_clk = %d \n " , i2s - > audio_pll_clk ) ;
i2s - > samplingrate = fdtdec_get_int ( blob ,
node , " samsung,i2s-sampling-rate " , - 1 ) ;
error | = i2s - > samplingrate ;
debug ( " samplingrate = %d \n " , i2s - > samplingrate ) ;
i2s - > bitspersample = fdtdec_get_int ( blob ,
node , " samsung,i2s-bits-per-sample " , - 1 ) ;
error | = i2s - > bitspersample ;
debug ( " bitspersample = %d \n " , i2s - > bitspersample ) ;
i2s - > channels = fdtdec_get_int ( blob ,
node , " samsung,i2s-channels " , - 1 ) ;
error | = i2s - > channels ;
debug ( " channels = %d \n " , i2s - > channels ) ;
i2s - > rfs = fdtdec_get_int ( blob ,
node , " samsung,i2s-lr-clk-framesize " , - 1 ) ;
error | = i2s - > rfs ;
debug ( " rfs = %d \n " , i2s - > rfs ) ;
i2s - > bfs = fdtdec_get_int ( blob ,
node , " samsung,i2s-bit-clk-framesize " , - 1 ) ;
error | = i2s - > bfs ;
debug ( " bfs = %d \n " , i2s - > bfs ) ;
if ( error = = - 1 ) {
debug ( " fail to get wm8994 codec node properties \n " ) ;
debug ( " fail to get sound i2s node properties \n " ) ;
return - 1 ;
}
# else
i2s - > base_address = samsung_get_base_i2s ( ) ;
i2s - > audio_pll_clk = I2S_PLL_CLK ;
i2s - > samplingrate = I2S_SAMPLING_RATE ;
i2s - > bitspersample = I2S_BITS_PER_SAMPLE ;
i2s - > channels = I2S_CHANNELS ;
i2s - > rfs = I2S_RFS ;
i2s - > bfs = I2S_BFS ;
# endif
return 0 ;
}
/*
* Gets fdt values for codec config parameters
* Init codec
*
* @ param pcodec_info codec information structure
* @ param blob FDT blob
* @ return int value , 0 for success
* @ param blob FDT blob
* @ param pi2s_tx i2s parameters required by codec
* @ return int value , 0 for success
*/
static int get_sound_codec_values ( struct sound_codec_info * pcodec_info )
static int codec_init ( const void * blob , struct i2stx_info * pi2s_tx )
{
int error = 0 ;
int ret ;
const char * codectype ;
# ifdef CONFIG_OF_CONTROL
int node ;
codectype = AUDIO_CODEC ;
/* Get the node from FDT for sound */
node = fdtdec_next_compatible ( blob , 0 , COMPAT_SAMSUNG_EXYNOS5_SOUND ) ;
if ( node < = 0 ) {
debug ( " EXYNOS_SOUND: No node for sound in device tree \n " ) ;
debug ( " node = %d \n " , node ) ;
return - 1 ;
}
/*
* Get the pre - defined sound codec specific values from FDT .
* All of these are expected to be correct otherwise sound
* can not be played
*/
codectype = fdt_getprop ( blob , node , " samsung,codec-type " , NULL ) ;
debug ( " device = %s \n " , codectype ) ;
# else
codectype = AUDIO_CODEC ;
# endif
if ( ! strcmp ( codectype , " wm8994 " ) ) {
pcodec_info - > codec_type = CODEC_WM_8994 ;
error = get_sound_wm8994_values ( pcodec_info ) ;
/* Check the codec type and initialise the same */
ret = wm8994_init ( blob , WM8994_AIF2 ,
pi2s_tx - > samplingrate ,
( pi2s_tx - > samplingrate * ( pi2s_tx - > rfs ) ) ,
pi2s_tx - > bitspersample , pi2s_tx - > channels ) ;
} else {
error = - 1 ;
debug ( " %s: Unknown code type %s \n " , __func__ ,
codectype ) ;
return - 1 ;
}
if ( error = = - 1 ) {
debug ( " fail to get sound codec node properties \n " ) ;
if ( ret ) {
debug ( " %s: Codec init failed \n " , __func__ ) ;
return - 1 ;
}
return 0 ;
}
int sound_init ( void )
int sound_init ( const void * blob )
{
int ret ;
struct i2stx_info * pi2s_tx = & g_i2stx_pri ;
struct sound_codec_info * pcodec_info = & g_codec_info ;
/* Get the I2S Values */
get_sound_i2s_values ( pi2s_tx ) ;
if ( get_sound_i2s_values ( pi2s_tx , blob ) < 0 ) {
debug ( " FDT I2S values failed \n " ) ;
return - 1 ;
}
/* Get the codec Values */
if ( get_sound_codec_values ( pcodec_info ) < 0 )
if ( codec_init ( blob , pi2s_tx ) < 0 ) {
debug ( " Codec init failed \n " ) ;
return - 1 ;
}
ret = i2s_tx_init ( pi2s_tx ) ;
if ( ret ) {
@ -137,21 +185,6 @@ int sound_init(void)
return ret ;
}
/* Check the codec type and initialise the same */
if ( pcodec_info - > codec_type = = CODEC_WM_8994 ) {
ret = wm8994_init ( pcodec_info , WM8994_AIF2 ,
pi2s_tx - > samplingrate ,
( pi2s_tx - > samplingrate * ( pi2s_tx - > rfs ) ) ,
pi2s_tx - > bitspersample , pi2s_tx - > channels ) ;
} else {
debug ( " %s: Unknown code type %d \n " , __func__ ,
pcodec_info - > codec_type ) ;
return - 1 ;
}
if ( ret ) {
debug ( " %s: Codec init failed \n " , __func__ ) ;
return - 1 ;
}
return ret ;
}