#include #include #include #include static int mc_uda1380_init(struct snd_soc_pcm_runtime *rtd); static int mc_uda1380_startup(struct snd_pcm_substream *substream); static int mc_uda1380_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000 }; static struct snd_pcm_hw_constraint_list hw_rates = { .count = ARRAY_SIZE(rates), .list = rates, .mask = 0, }; static struct snd_soc_ops mc_uda1380_ops = { .startup = mc_uda1380_startup, .hw_params = mc_uda1380_hw_params, }; /* Multicore digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link mc_uda1380_dai[] = { { .name = "uda1380", .stream_name = "UDA1380 Duplex", .cpu_dai_name = "mc_i2s.2", .codec_dai_name = "uda1380-hifi", .init = mc_uda1380_init, .platform_name = "multicore-audio.2", .codec_name = "uda1380-codec.0-0018", .ops = &mc_uda1380_ops, }, }; static struct snd_soc_card mc_asoc = { .name = "mc_audio", .owner = THIS_MODULE, .dai_link = mc_uda1380_dai, .num_links = ARRAY_SIZE(mc_uda1380_dai), }; static struct platform_device *mc_snd_device; static int mc_uda1380_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; runtime->hw.rate_min = hw_rates.list[0]; runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1]; runtime->hw.rates = MC_PCM_RATES; return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_rates); } static int mc_uda1380_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; struct snd_soc_dai *codec_dai = rtd->codec_dai; int ret; /* set codec DAI configuration */ ret = snd_soc_dai_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 = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_CONT); if (ret < 0) return ret; return 0; } static int mc_uda1380_init(struct snd_soc_pcm_runtime *rtd) { return 0; } static int __init mc_audio_init(void) { int ret; mc_snd_device = platform_device_alloc("soc-audio", -1); if (!mc_snd_device) return -ENOMEM; platform_set_drvdata(mc_snd_device, &mc_asoc); ret = platform_device_add(mc_snd_device); if (ret) { platform_device_put(mc_snd_device); return ret; } return 0; } static void __exit mc_audio_exit(void) { platform_device_unregister(mc_snd_device); } late_initcall(mc_audio_init); module_exit(mc_audio_exit); MODULE_AUTHOR("Dmitry Podkhvatilin"); MODULE_DESCRIPTION("ALSA SoC MULTICORE"); MODULE_LICENSE("GPL");