1. 註冊Platform Device
-
static int __init smdk_audio_init(void)
-
{
-
int ret;
-
-
smdk_snd_device = platform_device_alloc("soc-audio", -1);
-
if (!smdk_snd_device)
-
return -ENOMEM;
-
-
platform_set_drvdata(smdk_snd_device, &smdk);
-
-
ret = platform_device_add(smdk_snd_device);
-
if (ret)
-
platform_device_put(smdk_snd_device);
-
-
return ret;
-
}
-
static struct snd_soc_dai_link smdk_dai[] = {
-
{ /* Primary DAI i/f */
-
.name = "WM8994 AIF1",
-
.stream_name = "Pri_Dai",
-
.cpu_dai_name = "samsung-i2s.0",
-
.codec_dai_name = "wm8994-aif1",
-
.platform_name = "samsung-audio",
-
.codec_name = "wm8994-codec",
-
.init = smdk_wm8994_init_paiftx,
-
.ops = &smdk_ops,
-
}, { /* Sec_Fifo Playback i/f */
-
.name = "Sec_FIFO TX",
-
.stream_name = "Sec_Dai",
-
.cpu_dai_name = "samsung-i2s.4",
-
.codec_dai_name = "wm8994-aif1",
-
.platform_name = "samsung-audio",
-
.codec_name = "wm8994-codec",
-
.ops = &smdk_ops,
-
},
-
};
-
-
static struct snd_soc_card smdk = {
-
.name = "SMDK-I2S",
-
.owner = THIS_MODULE,
-
.dai_link = smdk_dai,
-
.num_links = ARRAY_SIZE(smdk_dai),
-
};
-
snd_soc_dai_link(實例:smdk_dai[] )
-
snd_soc_ops(實例:smdk_ops )
2. 註冊Platform Driver
-
static int __init snd_soc_init(void)
-
{
-
......
-
return platform_driver_register(&soc_driver);
-
}
-
/* ASoC platform driver */
-
static struct platform_driver soc_driver = {
-
.driver = {
-
.name = "soc-audio",
-
.owner = THIS_MODULE,
-
.pm = &soc_pm_ops,
-
},
-
.probe = soc_probe,
-
.remove = soc_remove,
-
};
3. 初始化入口soc_probe()
-
/* bind DAIs */
-
for (i = 0; i < card->num_links; i++)
-
soc_bind_dai_link(card, i);
-
/* card bind complete so register a sound card */
-
ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-
card->owner, 0, &card->snd_card);
-
card->snd_card->dev = card->dev;
-
-
card->dapm.bias_level = SND_SOC_BIAS_OFF;
-
card->dapm.dev = card->dev;
-
card->dapm.card = card;
-
list_add(&card->dapm.list, &card->dapm_list);
-
/* initialise the sound card only once */
-
if (card->probe) {
-
ret = card->probe(card);
-
if (ret < 0)
-
goto card_probe_error;
-
}
-
-
/* early DAI link probe */
-
for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
-
order++) {
-
for (i = 0; i < card->num_links; i++) {
-
ret = soc_probe_dai_link(card, i, order);
-
if (ret < 0) {
-
pr_err("asoc: failed to instantiate card %s: %d\n",
-
card->name, ret);
-
goto probe_dai_err;
-
}
-
}
-
}
-
-
for (i = 0; i < card->num_aux_devs; i++) {
-
ret = soc_probe_aux_dev(card, i);
-
if (ret < 0) {
-
pr_err("asoc: failed to add auxiliary devices %s: %d\n",
-
card->name, ret);
-
goto probe_aux_dev_err;
-
}
-
}
-
static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
-
{
-
......
-
/* set default power off timeout */
-
rtd->pmdown_time = pmdown_time;
-
-
/* probe the cpu_dai */
-
if (!cpu_dai->probed &&
-
cpu_dai->driver->probe_order == order) {
-
-
if (cpu_dai->driver->probe) {
-
ret = cpu_dai->driver->probe(cpu_dai);
-
}
-
cpu_dai->probed = 1;
-
/* mark cpu_dai as probed and add to card dai list */
-
list_add(&cpu_dai->card_list, &card->dai_dev_list);
-
}
-
-
/* probe the CODEC */
-
if (!codec->probed &&
-
codec->driver->probe_order == order) {
-
ret = soc_probe_codec(card, codec);
-
}
-
-
/* probe the platform */
-
if (!platform->probed &&
-
platform->driver->probe_order == order) {
-
ret = soc_probe_platform(card, platform);
-
}
-
-
/* probe the CODEC DAI */
-
if (!codec_dai->probed && codec_dai->driver->probe_order == order) {
-
if (codec_dai->driver->probe) {
-
ret = codec_dai->driver->probe(codec_dai);
-
}
-
-
/* mark codec_dai as probed and add to card dai list */
-
codec_dai->probed = 1;
-
list_add(&codec_dai->card_list, &card->dai_dev_list);
-
}
-
-
/* complete DAI probe during last probe */
-
if (order != SND_SOC_COMP_ORDER_LAST)
-
return 0;
-
-
ret = soc_post_component_init(card, codec, num, 0);
-
if (ret)
-
return ret;
-
......
-
/* create the pcm */
-
ret = soc_new_pcm(rtd, num);
-
........
-
return 0;
-
}
-
/* create a new pcm */
-
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
-
{
-
......
-
struct snd_pcm_ops *soc_pcm_ops = &rtd->ops;
-
-
soc_pcm_ops->open = soc_pcm_open;
-
soc_pcm_ops->close = soc_pcm_close;
-
soc_pcm_ops->hw_params = soc_pcm_hw_params;
-
soc_pcm_ops->hw_free = soc_pcm_hw_free;
-
soc_pcm_ops->prepare = soc_pcm_prepare;
-
soc_pcm_ops->trigger = soc_pcm_trigger;
-
soc_pcm_ops->pointer = soc_pcm_pointer;
-
-
ret = snd_pcm_new(rtd->card->snd_card, new_name,
-
num, playback, capture, &pcm);
-
-
/* DAPM dai link stream work */
-
INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
-
-
rtd->pcm = pcm;
-
pcm->private_data = rtd;
-
if (platform->driver->ops) {
-
soc_pcm_ops->mmap = platform->driver->ops->mmap;
-
soc_pcm_ops->pointer = platform->driver->ops->pointer;
-
soc_pcm_ops->ioctl = platform->driver->ops->ioctl;
-
soc_pcm_ops->copy = platform->driver->ops->copy;
-
soc_pcm_ops->silence = platform->driver->ops->silence;
-
soc_pcm_ops->ack = platform->driver->ops->ack;
-
soc_pcm_ops->page = platform->driver->ops->page;
-
}
-
-
if (playback)
-
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops);
-
-
if (capture)
-
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops);
-
-
if (platform->driver->pcm_new) {
-
ret = platform->driver->pcm_new(rtd);
-
if (ret < 0) {
-
pr_err("asoc: platform pcm constructor failed\n");
-
return ret;
-
}
-
}
-
-
pcm->private_free = platform->driver->pcm_free;
-
return ret;
-
}
-
if (card->late_probe) {
-
ret = card->late_probe(card);
-
if (ret < 0) {
-
dev_err(card->dev, "%s late_probe() failed: %d\n",
-
card->name, ret);
-
goto probe_aux_dev_err;
-
}
-
}
-
-
snd_soc_dapm_new_widgets(&card->dapm);
-
-
if (card->fully_routed)
-
list_for_each_entry(codec, &card->codec_dev_list, card_list)
-
snd_soc_dapm_auto_nc_codec_pins(codec);
-
-
ret = snd_card_register(card->snd_card);
-
if (ret < 0) {
-
printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
-
goto probe_aux_dev_err;
-
}