linux/sound/soc/soc-compress.c
/**
 * 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.
 */
create a new compress.
@rtd: The runtime for which we will create compress
@num: the device index number (zero based - shared with normal PCMs)

0 for success, else error.
create a new compress . @rtd : The runtime for which we will create compress @num : the device index number ( zero based - shared with normal PCMs ) 0 for success else error .
int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
{
	struct snd_soc_component *component;
	struct snd_soc_rtdcom_list *rtdcom;
	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,
			"Compress ASoC: Multicodec not supported\n");
		return -EINVAL;
	}
	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;
	if (playback + capture != 1) {
		dev_err(rtd->card->dev,
			"Compress ASoC: Invalid direction for 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)
		return -ENOMEM;
	compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
				  GFP_KERNEL);
	if (!compr->ops) {
		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,
				"Compress ASoC: can't create compressed for %s: %d\n",
				rtd->dai_link->name, ret);
			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 {
		snprintf(new_name, sizeof(new_name), "%s %s-%d",
			rtd->dai_link->stream_name, codec_dai->name, num);
		memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
	}
	for_each_rtdcom(rtd, rtdcom) {
		component = rtdcom->component;
		if (!component->driver->compr_ops ||
		    !component->driver->compr_ops->copy)
			continue;
		compr->ops->copy = soc_compr_copy;
		break;
	}
	mutex_init(&compr->lock);
	ret = snd_compress_new(rtd->card->snd_card, num, direction,
				new_name, compr);
	if (ret < 0) {
		component = rtd->codec_dai->component;
		dev_err(component->dev,
			"Compress ASoC: can't create compress for codec %s: %d\n",
			component->name, ret);
		goto compr_err;
	}
	INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
	rtd->compr = compr;
	compr->private_data = rtd;
	dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
		 codec_dai->name, cpu_dai->name);
	return ret;
compr_err:
	kfree(compr);
	return ret;
}
int snd_soc_new_compress ( struct snd_soc_pcm_runtime * rtd , int num ) { struct snd_soc_component * component ; struct snd_soc_rtdcom_list * rtdcom ; 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 , " \n " ) ; return - EINVAL ; } 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 ; if ( playback + capture != 1 ) { dev_err ( rtd -> card -> dev , " \n " , playback , capture ) ; return - EINVAL ; } if ( playback ) direction = SND_COMPRESS_PLAYBACK ; else direction = SND_COMPRESS_CAPTURE ; compr = kzalloc ( sizeof ( * compr ) , GFP_KERNEL ) ; if ( ! compr ) return - ENOMEM ; compr -> ops = devm_kzalloc ( rtd -> card -> dev , sizeof ( soc_compr_ops ) , GFP_KERNEL ) ; if ( ! compr -> ops ) { ret = - ENOMEM ; goto compr_err ; } if ( rtd -> dai_link -> dynamic ) { snprintf ( new_name , sizeof ( new_name ) , " " , 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 , " \n " , rtd -> dai_link -> name , ret ) ; 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 { snprintf ( new_name , sizeof ( new_name ) , " " , rtd -> dai_link -> stream_name , codec_dai -> name , num ) ; memcpy ( compr -> ops , & soc_compr_ops , sizeof ( soc_compr_ops ) ) ; } for_each_rtdcom ( rtd , rtdcom ) { component = rtdcom -> component ; if ( ! component -> driver -> compr_ops || ! component -> driver -> compr_ops -> copy ) continue ; compr -> ops -> copy = soc_compr_copy ; break ; } mutex_init ( & compr -> lock ) ; ret = snd_compress_new ( rtd -> card -> snd_card , num , direction , new_name , compr ) ; if ( ret < 0 ) { component = rtd -> codec_dai -> component ; dev_err ( component -> dev , " \n " , component -> name , ret ) ; goto compr_err ; } INIT_DELAYED_WORK ( & rtd -> delayed_work , close_delayed_work ) ; rtd -> compr = compr ; compr -> private_data = rtd ; dev_info ( rtd -> card -> dev , " \n " , codec_dai -> name , cpu_dai -> name ) ; return ret ; compr_err : kfree ( compr ) ; return ret ; }
snd_soc_new_compress - create a new compress.
snd_soc_new_compress - create a new compress .
/* check client and interface hw capabilities */ /*
	 * Compress devices are unidirectional so only one of the directions
	 * should be set, check for that (xor)
	 */ /* DAPM dai link stream work */