参照元

説明

引数

返り値

参考

実装

/**
 * snd_soc_new_compress - create a new compress.
 *
 * @rtd: The runtime for which we will create compress
 * @num: the device index number (zero based - shared with normal PCMs)
 *
 * Return: 0 for success, else error.
 */
int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
{
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_platform *platform = rtd->platform;
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct snd_compr *compr;
        struct snd_pcm *be_pcm;
        char new_name[64];
        int ret = 0, direction = 0;
        int playback = 0, capture = 0;
        if (rtd->num_codecs > 1) {
                dev_err(rtd->card->dev, "Multicodec not supported for compressed stream\n");
                return -EINVAL;
        }
        /* check client and interface hw capabilities */
        snprintf(new_name, sizeof(new_name), "%s %s-%d",
                        rtd->dai_link->stream_name, codec_dai->name, num);
        if (codec_dai->driver->playback.channels_min)
                playback = 1;
        if (codec_dai->driver->capture.channels_min)
                capture = 1;
        capture = capture && cpu_dai->driver->capture.channels_min;
        playback = playback && cpu_dai->driver->playback.channels_min;

        /*
         * Compress devices are unidirectional so only one of the directions
         * should be set, check for that (xor)
         */
        if (playback + capture != 1) {
                dev_err(rtd->card->dev, "Invalid direction for compress P %d, C %d\n",
                                playback, capture);
                return -EINVAL;
        }

        if(playback)
                direction = SND_COMPRESS_PLAYBACK;
        else
                direction = SND_COMPRESS_CAPTURE;

        compr = kzalloc(sizeof(*compr), GFP_KERNEL);
        if (compr == NULL) {
                snd_printk(KERN_ERR "Cannot allocate compr\n");
                return -ENOMEM;
        }
        compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
                                  GFP_KERNEL);
        if (compr->ops == NULL) {
                dev_err(rtd->card->dev, "Cannot allocate compressed ops\n");
                ret = -ENOMEM;
                goto compr_err;
        }
        if (rtd->dai_link->dynamic) {
                snprintf(new_name, sizeof(new_name), "(%s)",
                        rtd->dai_link->stream_name);

                ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
                                rtd->dai_link->dpcm_playback,
                                rtd->dai_link->dpcm_capture, &be_pcm);
                if (ret < 0) {
                        dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n",
                                rtd->dai_link->name);
                        goto compr_err;
                }
                rtd->pcm = be_pcm;
                rtd->fe_compr = 1;
                if (rtd->dai_link->dpcm_playback)
                        be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
                else if (rtd->dai_link->dpcm_capture)
                        be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
                memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
        } else
                memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));

        /* Add copy callback for not memory mapped DSPs */
        if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
                compr->ops->copy = soc_compr_copy;

        mutex_init(&compr->lock);
        ret = snd_compress_new(rtd->card->snd_card, num, direction, compr);
        if (ret < 0) {
                pr_err("compress asoc: can't create compress for codec %s\n",
                        codec->component.name);
                goto compr_err;
        }
        /* DAPM dai link stream work */
        INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
        rtd->compr = compr;
        compr->private_data = rtd;

        printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
                cpu_dai->name);
        return ret;
compr_err:
        kfree(compr);
        return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_new_compress);

コメント


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS