linux alsa驱动
//
struct snd_card *card;
struct snd_pcm *pcm;
err = snd_card_new(&g_audio->gadget->dev,
-1, NULL, THIS_MODULE, 0, &card);
err = snd_pcm_new(uac->card, pcm_name, 0,
p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm);
if (err < 0)
goto snd_fail;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops);
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);
err = snd_card_register(card);
snd_fail:
snd_card_free(card);
// read|write:
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
/* Pack USB load in ALSA ring buffer */
pending = runtime->dma_bytes - hw_ptr;
case read:
memcpy(runtime->dma_area + hw_ptr, req->buf, pending);
memcpy(runtime->dma_area, req->buf + pending,
req->actual - pending);
case write:
memcpy(req->buf, runtime->dma_area + hw_ptr, pending);
memcpy(req->buf + pending, runtime->dma_area,
req->actual - pending);
if ((hw_ptr % snd_pcm_lib_period_bytes(substream)) < req->actual)
snd_pcm_period_elapsed(substream);
machine:
snd_soc_card_set_drvdata(&priv->snd_card, priv);
ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
codec:
snd_soc_register_codec(dev, &soc_codec_dev_tlv320aic23,
&tlv320aic23_dai, 1);
platform:
ret = devm_snd_soc_register_component(&pdev->dev,
&rockchip_i2s_component,
soc_dai, 1);
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (ret) {
dev_err(&pdev->dev, "Could not register PCM\n");
return ret;
}
一勤天下无难事。

浙公网安备 33010602011771号