diff options
| -rw-r--r-- | drivers/sound/sound.c | 171 | ||||
| -rw-r--r-- | include/sound.h | 4 | 
2 files changed, 104 insertions, 71 deletions
| diff --git a/drivers/sound/sound.c b/drivers/sound/sound.c index 4c74534c9..fa8432d48 100644 --- a/drivers/sound/sound.c +++ b/drivers/sound/sound.c @@ -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;  } diff --git a/include/sound.h b/include/sound.h index ea0b1158f..d73839d9f 100644 --- a/include/sound.h +++ b/include/sound.h @@ -46,10 +46,10 @@ struct sound_codec_info {  /*   * Initialises audio sub system - * + * @param blob	Pointer of device tree node or NULL if none.   * @return	int value 0 for success, -1 for error   */ -int sound_init(void); +int sound_init(const void *blob);  /*   * plays the pcm data buffer in pcm_data.h through i2s1 to make the |