diff --git a/sound/soc/bcm/audioinjector-pi-soundcard.c b/sound/soc/bcm/audioinjector-pi-soundcard.c index 39f29e2689722..5ff0985e07efb 100644 --- a/sound/soc/bcm/audioinjector-pi-soundcard.c +++ b/sound/soc/bcm/audioinjector-pi-soundcard.c @@ -29,16 +29,56 @@ #include "../codecs/wm8731.h" -static int audioinjector_pi_soundcard_dai_init(struct snd_soc_pcm_runtime *rtd) +static const unsigned int bcm2835_rates_12000000[] = { + 32000, 44100, 48000, 96000, 88200, +}; + +static struct snd_pcm_hw_constraint_list bcm2835_constraints_12000000 = { + .list = bcm2835_rates_12000000, + .count = ARRAY_SIZE(bcm2835_rates_12000000), +}; + +static int snd_audioinjector_pi_soundcard_startup(struct snd_pcm_substream *substream) { - struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + /* Setup constraints, because there is a 12 MHz XTAL on the board */ + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &bcm2835_constraints_12000000); + return 0; +} - // not connected - snd_soc_dapm_nc_pin(dapm, "Mic Bias"); - snd_soc_dapm_nc_pin(dapm, "MICIN"); - snd_soc_dapm_nc_pin(dapm, "RHPOUT"); - snd_soc_dapm_nc_pin(dapm, "LHPOUT"); +static int snd_audioinjector_pi_soundcard_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_dai *cpu_dai = rtd->cpu_dai; + + switch (params_rate(params)){ + case 8000: + return snd_soc_dai_set_bclk_ratio(cpu_dai, 1508); + case 32000: + return snd_soc_dai_set_bclk_ratio(cpu_dai, 378); + case 44100: + return snd_soc_dai_set_bclk_ratio(cpu_dai, 274); + case 48000: + return snd_soc_dai_set_bclk_ratio(cpu_dai, 252); + case 88200: + return snd_soc_dai_set_bclk_ratio(cpu_dai, 136); + case 96000: + return snd_soc_dai_set_bclk_ratio(cpu_dai, 126); + default: + return snd_soc_dai_set_bclk_ratio(cpu_dai, 126); + } +} + +/* machine stream operations */ +static struct snd_soc_ops snd_audioinjector_pi_soundcard_ops = { + .startup = snd_audioinjector_pi_soundcard_startup, + .hw_params = snd_audioinjector_pi_soundcard_hw_params, +}; +static int audioinjector_pi_soundcard_dai_init(struct snd_soc_pcm_runtime *rtd) +{ return snd_soc_dai_set_sysclk(rtd->codec_dai, WM8731_SYSCLK_XTAL, 12000000, SND_SOC_CLOCK_IN); } @@ -50,30 +90,39 @@ static struct snd_soc_dai_link audioinjector_pi_soundcard_dai[] = { .codec_dai_name = "wm8731-hifi", .platform_name = "bcm2835-i2s.0", .codec_name = "wm8731.1-001a", + .ops = &snd_audioinjector_pi_soundcard_ops, .init = audioinjector_pi_soundcard_dai_init, .dai_fmt = SND_SOC_DAIFMT_CBM_CFM|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF, }, }; static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_SPK("Ext Spk", NULL), SND_SOC_DAPM_LINE("Line In Jacks", NULL), + SND_SOC_DAPM_MIC("Microphone", NULL), }; -/* Corgi machine connections to the codec pins */ static const struct snd_soc_dapm_route audioinjector_audio_map[] = { + /* headphone connected to LHPOUT, RHPOUT */ + {"Headphone Jack", NULL, "LHPOUT"}, + {"Headphone Jack", NULL, "RHPOUT"}, + /* speaker connected to LOUT, ROUT */ {"Ext Spk", NULL, "ROUT"}, {"Ext Spk", NULL, "LOUT"}, /* line inputs */ {"Line In Jacks", NULL, "Line Input"}, + + /* mic is connected to Mic Jack, with WM8731 Mic Bias */ + {"Microphone", NULL, "Mic Bias"}, }; static struct snd_soc_card snd_soc_audioinjector = { .name = "audioinjector-pi-soundcard", .dai_link = audioinjector_pi_soundcard_dai, - .num_links = 1, + .num_links = ARRAY_SIZE(audioinjector_pi_soundcard_dai), .dapm_widgets = wm8731_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),