brintos

brintos / linux-shallow public Read only

0
0
Text · 17.6 KiB · e692aa3 Raw
670 lines · c
1// SPDX-License-Identifier: GPL-2.0+2//3// soc-compress.c  --  ALSA SoC Compress4//5// Copyright (C) 2012 Intel Corp.6//7// Authors: Namarta Kohli <namartax.kohli@intel.com>8//          Ramesh Babu K V <ramesh.babu@linux.intel.com>9//          Vinod Koul <vinod.koul@linux.intel.com>10 11#include <linux/kernel.h>12#include <linux/init.h>13#include <linux/delay.h>14#include <linux/slab.h>15#include <linux/workqueue.h>16#include <sound/core.h>17#include <sound/compress_params.h>18#include <sound/compress_driver.h>19#include <sound/soc.h>20#include <sound/initval.h>21#include <sound/soc-dpcm.h>22#include <sound/soc-link.h>23 24static int snd_soc_compr_components_open(struct snd_compr_stream *cstream)25{26	struct snd_soc_pcm_runtime *rtd = cstream->private_data;27	struct snd_soc_component *component;28	int ret = 0;29	int i;30 31	for_each_rtd_components(rtd, i, component) {32		ret = snd_soc_component_module_get_when_open(component, cstream);33		if (ret < 0)34			break;35 36		ret = snd_soc_component_compr_open(component, cstream);37		if (ret < 0)38			break;39	}40 41	return ret;42}43 44static void snd_soc_compr_components_free(struct snd_compr_stream *cstream,45					  int rollback)46{47	struct snd_soc_pcm_runtime *rtd = cstream->private_data;48	struct snd_soc_component *component;49	int i;50 51	for_each_rtd_components(rtd, i, component) {52		snd_soc_component_compr_free(component, cstream, rollback);53		snd_soc_component_module_put_when_close(component, cstream, rollback);54	}55}56 57static int soc_compr_clean(struct snd_compr_stream *cstream, int rollback)58{59	struct snd_soc_pcm_runtime *rtd = cstream->private_data;60	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);61	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);62	int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */63 64	snd_soc_dpcm_mutex_lock(rtd);65 66	if (!rollback)67		snd_soc_runtime_deactivate(rtd, stream);68 69	snd_soc_dai_digital_mute(codec_dai, 1, stream);70 71	if (!snd_soc_dai_active(cpu_dai))72		cpu_dai->rate = 0;73 74	if (!snd_soc_dai_active(codec_dai))75		codec_dai->rate = 0;76 77	snd_soc_link_compr_shutdown(cstream, rollback);78 79	snd_soc_compr_components_free(cstream, rollback);80 81	snd_soc_dai_compr_shutdown(cpu_dai, cstream, rollback);82 83	if (!rollback)84		snd_soc_dapm_stream_stop(rtd, stream);85 86	snd_soc_dpcm_mutex_unlock(rtd);87 88	snd_soc_pcm_component_pm_runtime_put(rtd, cstream, rollback);89 90	return 0;91}92 93static int soc_compr_free(struct snd_compr_stream *cstream)94{95	return soc_compr_clean(cstream, 0);96}97 98static int soc_compr_open(struct snd_compr_stream *cstream)99{100	struct snd_soc_pcm_runtime *rtd = cstream->private_data;101	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);102	int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */103	int ret;104 105	ret = snd_soc_pcm_component_pm_runtime_get(rtd, cstream);106	if (ret < 0)107		goto err_no_lock;108 109	snd_soc_dpcm_mutex_lock(rtd);110 111	ret = snd_soc_dai_compr_startup(cpu_dai, cstream);112	if (ret < 0)113		goto err;114 115	ret = snd_soc_compr_components_open(cstream);116	if (ret < 0)117		goto err;118 119	ret = snd_soc_link_compr_startup(cstream);120	if (ret < 0)121		goto err;122 123	snd_soc_runtime_activate(rtd, stream);124err:125	snd_soc_dpcm_mutex_unlock(rtd);126err_no_lock:127	if (ret < 0)128		soc_compr_clean(cstream, 1);129 130	return ret;131}132 133static int soc_compr_open_fe(struct snd_compr_stream *cstream)134{135	struct snd_soc_pcm_runtime *fe = cstream->private_data;136	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(fe, 0);137	struct snd_soc_dpcm *dpcm;138	struct snd_soc_dapm_widget_list *list;139	int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */140	int ret;141 142	snd_soc_card_mutex_lock(fe->card);143 144	ret = dpcm_path_get(fe, stream, &list);145	if (ret < 0)146		goto be_err;147 148	snd_soc_dpcm_mutex_lock(fe);149 150	/* calculate valid and active FE <-> BE dpcms */151	dpcm_process_paths(fe, stream, &list, 1);152 153	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;154 155	ret = dpcm_be_dai_startup(fe, stream);156	if (ret < 0) {157		/* clean up all links */158		for_each_dpcm_be(fe, stream, dpcm)159			dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;160 161		dpcm_be_disconnect(fe, stream);162		goto out;163	}164 165	ret = snd_soc_dai_compr_startup(cpu_dai, cstream);166	if (ret < 0)167		goto out;168 169	ret = snd_soc_compr_components_open(cstream);170	if (ret < 0)171		goto open_err;172 173	ret = snd_soc_link_compr_startup(cstream);174	if (ret < 0)175		goto machine_err;176 177	dpcm_clear_pending_state(fe, stream);178	dpcm_path_put(&list);179 180	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;181	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;182 183	snd_soc_runtime_activate(fe, stream);184	snd_soc_dpcm_mutex_unlock(fe);185 186	snd_soc_card_mutex_unlock(fe->card);187 188	return 0;189 190machine_err:191	snd_soc_compr_components_free(cstream, 1);192open_err:193	snd_soc_dai_compr_shutdown(cpu_dai, cstream, 1);194out:195	dpcm_path_put(&list);196	snd_soc_dpcm_mutex_unlock(fe);197be_err:198	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;199	snd_soc_card_mutex_unlock(fe->card);200	return ret;201}202 203static int soc_compr_free_fe(struct snd_compr_stream *cstream)204{205	struct snd_soc_pcm_runtime *fe = cstream->private_data;206	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(fe, 0);207	struct snd_soc_dpcm *dpcm;208	int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */209 210	snd_soc_card_mutex_lock(fe->card);211 212	snd_soc_dpcm_mutex_lock(fe);213	snd_soc_runtime_deactivate(fe, stream);214 215	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;216 217	dpcm_be_dai_hw_free(fe, stream);218 219	dpcm_be_dai_shutdown(fe, stream);220 221	/* mark FE's links ready to prune */222	for_each_dpcm_be(fe, stream, dpcm)223		dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;224 225	dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);226 227	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;228	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;229 230	dpcm_be_disconnect(fe, stream);231 232	snd_soc_dpcm_mutex_unlock(fe);233 234	snd_soc_link_compr_shutdown(cstream, 0);235 236	snd_soc_compr_components_free(cstream, 0);237 238	snd_soc_dai_compr_shutdown(cpu_dai, cstream, 0);239 240	snd_soc_card_mutex_unlock(fe->card);241	return 0;242}243 244static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)245{246	struct snd_soc_pcm_runtime *rtd = cstream->private_data;247	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);248	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);249	int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */250	int ret;251 252	snd_soc_dpcm_mutex_lock(rtd);253 254	ret = snd_soc_component_compr_trigger(cstream, cmd);255	if (ret < 0)256		goto out;257 258	ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);259	if (ret < 0)260		goto out;261 262	switch (cmd) {263	case SNDRV_PCM_TRIGGER_START:264		snd_soc_dai_digital_mute(codec_dai, 0, stream);265		break;266	case SNDRV_PCM_TRIGGER_STOP:267		snd_soc_dai_digital_mute(codec_dai, 1, stream);268		break;269	}270 271out:272	snd_soc_dpcm_mutex_unlock(rtd);273	return ret;274}275 276static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)277{278	struct snd_soc_pcm_runtime *fe = cstream->private_data;279	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(fe, 0);280	int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */281	int ret;282 283	if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||284	    cmd == SND_COMPR_TRIGGER_DRAIN)285		return snd_soc_component_compr_trigger(cstream, cmd);286 287	snd_soc_card_mutex_lock(fe->card);288 289	ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);290	if (ret < 0)291		goto out;292 293	ret = snd_soc_component_compr_trigger(cstream, cmd);294	if (ret < 0)295		goto out;296 297	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;298 299	ret = dpcm_be_dai_trigger(fe, stream, cmd);300 301	switch (cmd) {302	case SNDRV_PCM_TRIGGER_START:303	case SNDRV_PCM_TRIGGER_RESUME:304	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:305		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;306		break;307	case SNDRV_PCM_TRIGGER_STOP:308	case SNDRV_PCM_TRIGGER_SUSPEND:309		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;310		break;311	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:312		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;313		break;314	}315 316out:317	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;318	snd_soc_card_mutex_unlock(fe->card);319	return ret;320}321 322static int soc_compr_set_params(struct snd_compr_stream *cstream,323				struct snd_compr_params *params)324{325	struct snd_soc_pcm_runtime *rtd = cstream->private_data;326	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);327	int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */328	int ret;329 330	snd_soc_dpcm_mutex_lock(rtd);331 332	/*333	 * First we call set_params for the CPU DAI, then the component334	 * driver this should configure the SoC side. If the machine has335	 * compressed ops then we call that as well. The expectation is336	 * that these callbacks will configure everything for this compress337	 * path, like configuring a PCM port for a CODEC.338	 */339	ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);340	if (ret < 0)341		goto err;342 343	ret = snd_soc_component_compr_set_params(cstream, params);344	if (ret < 0)345		goto err;346 347	ret = snd_soc_link_compr_set_params(cstream);348	if (ret < 0)349		goto err;350 351	snd_soc_dapm_stream_event(rtd, stream, SND_SOC_DAPM_STREAM_START);352 353	/* cancel any delayed stream shutdown that is pending */354	rtd->pop_wait = 0;355	snd_soc_dpcm_mutex_unlock(rtd);356 357	cancel_delayed_work_sync(&rtd->delayed_work);358 359	return 0;360 361err:362	snd_soc_dpcm_mutex_unlock(rtd);363	return ret;364}365 366static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,367				   struct snd_compr_params *params)368{369	struct snd_soc_pcm_runtime *fe = cstream->private_data;370	struct snd_pcm_substream *fe_substream =371		 fe->pcm->streams[cstream->direction].substream;372	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(fe, 0);373	int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */374	int ret;375 376	snd_soc_card_mutex_lock(fe->card);377 378	/*379	 * Create an empty hw_params for the BE as the machine driver must380	 * fix this up to match DSP decoder and ASRC configuration.381	 * I.e. machine driver fixup for compressed BE is mandatory.382	 */383	memset(&fe->dpcm[fe_substream->stream].hw_params, 0,384		sizeof(struct snd_pcm_hw_params));385 386	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;387 388	snd_soc_dpcm_mutex_lock(fe);389	ret = dpcm_be_dai_hw_params(fe, stream);390	snd_soc_dpcm_mutex_unlock(fe);391	if (ret < 0)392		goto out;393 394	snd_soc_dpcm_mutex_lock(fe);395	ret = dpcm_be_dai_prepare(fe, stream);396	snd_soc_dpcm_mutex_unlock(fe);397	if (ret < 0)398		goto out;399 400	ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);401	if (ret < 0)402		goto out;403 404	ret = snd_soc_component_compr_set_params(cstream, params);405	if (ret < 0)406		goto out;407 408	ret = snd_soc_link_compr_set_params(cstream);409	if (ret < 0)410		goto out;411	snd_soc_dpcm_mutex_lock(fe);412	dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);413	snd_soc_dpcm_mutex_unlock(fe);414	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;415 416out:417	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;418	snd_soc_card_mutex_unlock(fe->card);419	return ret;420}421 422static int soc_compr_get_params(struct snd_compr_stream *cstream,423				struct snd_codec *params)424{425	struct snd_soc_pcm_runtime *rtd = cstream->private_data;426	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);427	int ret = 0;428 429	snd_soc_dpcm_mutex_lock(rtd);430 431	ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params);432	if (ret < 0)433		goto err;434 435	ret = snd_soc_component_compr_get_params(cstream, params);436err:437	snd_soc_dpcm_mutex_unlock(rtd);438	return ret;439}440 441static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)442{443	struct snd_soc_pcm_runtime *rtd = cstream->private_data;444	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);445	int ret;446 447	snd_soc_dpcm_mutex_lock(rtd);448 449	ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes);450	if (ret < 0)451		goto err;452 453	ret = snd_soc_component_compr_ack(cstream, bytes);454err:455	snd_soc_dpcm_mutex_unlock(rtd);456	return ret;457}458 459static int soc_compr_pointer(struct snd_compr_stream *cstream,460			     struct snd_compr_tstamp *tstamp)461{462	struct snd_soc_pcm_runtime *rtd = cstream->private_data;463	int ret;464	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);465 466	snd_soc_dpcm_mutex_lock(rtd);467 468	ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp);469	if (ret < 0)470		goto out;471 472	ret = snd_soc_component_compr_pointer(cstream, tstamp);473out:474	snd_soc_dpcm_mutex_unlock(rtd);475	return ret;476}477 478static int soc_compr_set_metadata(struct snd_compr_stream *cstream,479				  struct snd_compr_metadata *metadata)480{481	struct snd_soc_pcm_runtime *rtd = cstream->private_data;482	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);483	int ret;484 485	ret = snd_soc_dai_compr_set_metadata(cpu_dai, cstream, metadata);486	if (ret < 0)487		return ret;488 489	return snd_soc_component_compr_set_metadata(cstream, metadata);490}491 492static int soc_compr_get_metadata(struct snd_compr_stream *cstream,493				  struct snd_compr_metadata *metadata)494{495	struct snd_soc_pcm_runtime *rtd = cstream->private_data;496	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);497	int ret;498 499	ret = snd_soc_dai_compr_get_metadata(cpu_dai, cstream, metadata);500	if (ret < 0)501		return ret;502 503	return snd_soc_component_compr_get_metadata(cstream, metadata);504}505 506/* ASoC Compress operations */507static struct snd_compr_ops soc_compr_ops = {508	.open		= soc_compr_open,509	.free		= soc_compr_free,510	.set_params	= soc_compr_set_params,511	.set_metadata   = soc_compr_set_metadata,512	.get_metadata	= soc_compr_get_metadata,513	.get_params	= soc_compr_get_params,514	.trigger	= soc_compr_trigger,515	.pointer	= soc_compr_pointer,516	.ack		= soc_compr_ack,517	.get_caps	= snd_soc_component_compr_get_caps,518	.get_codec_caps = snd_soc_component_compr_get_codec_caps,519};520 521/* ASoC Dynamic Compress operations */522static struct snd_compr_ops soc_compr_dyn_ops = {523	.open		= soc_compr_open_fe,524	.free		= soc_compr_free_fe,525	.set_params	= soc_compr_set_params_fe,526	.get_params	= soc_compr_get_params,527	.set_metadata   = soc_compr_set_metadata,528	.get_metadata	= soc_compr_get_metadata,529	.trigger	= soc_compr_trigger_fe,530	.pointer	= soc_compr_pointer,531	.ack		= soc_compr_ack,532	.get_caps	= snd_soc_component_compr_get_caps,533	.get_codec_caps = snd_soc_component_compr_get_codec_caps,534};535 536/**537 * snd_soc_new_compress - create a new compress.538 *539 * @rtd: The runtime for which we will create compress540 * @num: the device index number (zero based - shared with normal PCMs)541 *542 * Return: 0 for success, else error.543 */544int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)545{546	struct snd_soc_component *component;547	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);548	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);549	struct snd_compr *compr;550	struct snd_pcm *be_pcm;551	char new_name[64];552	int ret = 0, direction = 0;553	int playback = 0, capture = 0;554	int i;555 556	/*557	 * make sure these are same value,558	 * and then use these as equally559	 */560	BUILD_BUG_ON((int)SNDRV_PCM_STREAM_PLAYBACK != (int)SND_COMPRESS_PLAYBACK);561	BUILD_BUG_ON((int)SNDRV_PCM_STREAM_CAPTURE  != (int)SND_COMPRESS_CAPTURE);562 563	if (rtd->dai_link->num_cpus > 1 ||564	    rtd->dai_link->num_codecs > 1) {565		dev_err(rtd->card->dev,566			"Compress ASoC: Multi CPU/Codec not supported\n");567		return -EINVAL;568	}569 570	if (!codec_dai) {571		dev_err(rtd->card->dev, "Missing codec\n");572		return -EINVAL;573	}574 575	/* check client and interface hw capabilities */576	if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&577	    snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_PLAYBACK))578		playback = 1;579	if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&580	    snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_CAPTURE))581		capture = 1;582 583	/*584	 * Compress devices are unidirectional so only one of the directions585	 * should be set, check for that (xor)586	 */587	if (playback + capture != 1) {588		dev_err(rtd->card->dev,589			"Compress ASoC: Invalid direction for P %d, C %d\n",590			playback, capture);591		return -EINVAL;592	}593 594	if (playback)595		direction = SND_COMPRESS_PLAYBACK;596	else597		direction = SND_COMPRESS_CAPTURE;598 599	compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL);600	if (!compr)601		return -ENOMEM;602 603	compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),604				  GFP_KERNEL);605	if (!compr->ops)606		return -ENOMEM;607 608	if (rtd->dai_link->dynamic) {609		snprintf(new_name, sizeof(new_name), "(%s)",610			rtd->dai_link->stream_name);611 612		ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,613				rtd->dai_link->dpcm_playback,614				rtd->dai_link->dpcm_capture, &be_pcm);615		if (ret < 0) {616			dev_err(rtd->card->dev,617				"Compress ASoC: can't create compressed for %s: %d\n",618				rtd->dai_link->name, ret);619			return ret;620		}621 622		/* inherit atomicity from DAI link */623		be_pcm->nonatomic = rtd->dai_link->nonatomic;624 625		rtd->pcm = be_pcm;626		rtd->fe_compr = 1;627		if (rtd->dai_link->dpcm_playback)628			be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;629		if (rtd->dai_link->dpcm_capture)630			be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;631		memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));632	} else {633		snprintf(new_name, sizeof(new_name), "%s %s-%d",634			rtd->dai_link->stream_name, codec_dai->name, num);635 636		memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));637	}638 639	for_each_rtd_components(rtd, i, component) {640		if (!component->driver->compress_ops ||641		    !component->driver->compress_ops->copy)642			continue;643 644		compr->ops->copy = snd_soc_component_compr_copy;645		break;646	}647 648	ret = snd_compress_new(rtd->card->snd_card, num, direction,649				new_name, compr);650	if (ret < 0) {651		component = snd_soc_rtd_to_codec(rtd, 0)->component;652		dev_err(component->dev,653			"Compress ASoC: can't create compress for codec %s: %d\n",654			component->name, ret);655		return ret;656	}657 658	/* DAPM dai link stream work */659	rtd->close_delayed_work_func = snd_soc_close_delayed_work;660 661	rtd->compr = compr;662	compr->private_data = rtd;663 664	dev_dbg(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",665		codec_dai->name, cpu_dai->name);666 667	return 0;668}669EXPORT_SYMBOL_GPL(snd_soc_new_compress);670