diff options
Diffstat (limited to 'sound/soc/pxa')
-rw-r--r-- | sound/soc/pxa/corgi.c | 84 |
1 files changed, 53 insertions, 31 deletions
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 2b1c6e94d1e..5ee51a994ac 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -37,6 +37,7 @@ #include "../codecs/wm8731.h" #include "pxa2xx-pcm.h" +#include "pxa2xx-i2s.h" #define CORGI_HP 0 #define CORGI_MIC 1 @@ -119,8 +120,59 @@ static int corgi_shutdown(struct snd_pcm_substream *substream) return 0; } +static int corgi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + unsigned int clk = 0; + int ret = 0; + + switch (params_rate(params)) { + case 8000: + case 16000: + case 48000: + case 96000: + clk = 12288000; + break; + case 11025: + case 22050: + case 44100: + clk = 11289600; + break; + } + + /* set codec DAI configuration */ + ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set the codec system clock for DAC and ADC */ + ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set the I2S system clock as input (unused) */ + ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + static struct snd_soc_ops corgi_ops = { .startup = corgi_startup, + .hw_params = corgi_hw_params, .shutdown = corgi_shutdown, }; @@ -264,35 +316,6 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec) return 0; } -static unsigned int corgi_config_sysclk(struct snd_soc_pcm_runtime *rtd, - struct snd_soc_clock_info *info) -{ - if (info->bclk_master & SND_SOC_DAIFMT_CBS_CFS) { - /* pxa2xx is i2s master */ - switch (info->rate) { - case 44100: - case 88200: - /* configure codec digital filters for 44.1, 88.2 */ - rtd->codec_dai->config_sysclk(rtd->codec_dai, info, - 11289600); - break; - default: - /* configure codec digital filters for all other rates */ - rtd->codec_dai->config_sysclk(rtd->codec_dai, info, - CORGI_AUDIO_CLOCK); - break; - } - /* config pxa i2s as master */ - return rtd->cpu_dai->config_sysclk(rtd->cpu_dai, info, - CORGI_AUDIO_CLOCK); - } else { - /* codec is i2s master - - * only configure codec DAI clock and filters */ - return rtd->codec_dai->config_sysclk(rtd->codec_dai, info, - CORGI_AUDIO_CLOCK); - } -} - /* corgi digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link corgi_dai = { .name = "WM8731", @@ -300,7 +323,7 @@ static struct snd_soc_dai_link corgi_dai = { .cpu_dai = &pxa_i2s_dai, .codec_dai = &wm8731_dai, .init = corgi_wm8731_init, - .config_sysclk = corgi_config_sysclk, + .ops = &corgi_ops, }; /* corgi audio machine driver */ @@ -308,7 +331,6 @@ static struct snd_soc_machine snd_soc_machine_corgi = { .name = "Corgi", .dai_link = &corgi_dai, .num_links = 1, - .ops = &corgi_ops, }; /* corgi audio private data */ |