Blame view

sound/soc/soc-compress.c 22.1 KB
b3ed4c86a   Kuninori Morimoto   ASoC: soc-compres...
1
2
3
4
5
6
7
8
9
  // SPDX-License-Identifier: GPL-2.0+
  //
  // soc-compress.c  --  ALSA SoC Compress
  //
  // Copyright (C) 2012 Intel Corp.
  //
  // Authors: Namarta Kohli <namartax.kohli@intel.com>
  //          Ramesh Babu K V <ramesh.babu@linux.intel.com>
  //          Vinod Koul <vinod.koul@linux.intel.com>
1245b7005   Namarta Kohli   ASoC: add compres...
10
11
12
13
14
15
16
17
18
19
20
  
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/delay.h>
  #include <linux/slab.h>
  #include <linux/workqueue.h>
  #include <sound/core.h>
  #include <sound/compress_params.h>
  #include <sound/compress_driver.h>
  #include <sound/soc.h>
  #include <sound/initval.h>
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
21
  #include <sound/soc-dpcm.h>
9ab711cb8   Kuninori Morimoto   ASoC: soc-link: a...
22
  #include <sound/soc-link.h>
4137f4b65   Cezary Rojewski   ASoC: compress: A...
23
  #include <linux/pm_runtime.h>
1245b7005   Namarta Kohli   ASoC: add compres...
24

1e57b8289   Charles Keepax   ASoC: compress: A...
25
26
  static int soc_compr_components_open(struct snd_compr_stream *cstream,
  				     struct snd_soc_component **last)
1245b7005   Namarta Kohli   ASoC: add compres...
27
28
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
29
  	struct snd_soc_component *component;
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
30
  	int i, ret;
1245b7005   Namarta Kohli   ASoC: add compres...
31

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
32
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->open)
  			continue;
  
  		ret = component->driver->compress_ops->open(component, cstream);
  		if (ret < 0) {
  			dev_err(component->dev,
  				"Compress ASoC: can't open platform %s: %d
  ",
  				component->name, ret);
  
  			*last = component;
  			return ret;
  		}
  	}
1e57b8289   Charles Keepax   ASoC: compress: A...
48
49
50
51
52
53
54
55
56
  	*last = NULL;
  	return 0;
  }
  
  static int soc_compr_components_free(struct snd_compr_stream *cstream,
  				     struct snd_soc_component *last)
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  	struct snd_soc_component *component;
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
57
  	int i;
1e57b8289   Charles Keepax   ASoC: compress: A...
58

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
59
  	for_each_rtd_components(rtd, i, component) {
1e57b8289   Charles Keepax   ASoC: compress: A...
60
61
  		if (component == last)
  			break;
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
62
63
64
65
66
67
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->free)
  			continue;
  
  		component->driver->compress_ops->free(component, cstream);
  	}
1e57b8289   Charles Keepax   ASoC: compress: A...
68
69
70
71
72
73
  	return 0;
  }
  
  static int soc_compr_open(struct snd_compr_stream *cstream)
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
939a5cfb2   Kuninori Morimoto   ASoC: soc-compone...
74
  	struct snd_soc_component *component = NULL;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
75
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
939a5cfb2   Kuninori Morimoto   ASoC: soc-compone...
76
  	int ret;
1e57b8289   Charles Keepax   ASoC: compress: A...
77

939a5cfb2   Kuninori Morimoto   ASoC: soc-compone...
78
79
80
  	ret = snd_soc_pcm_component_pm_runtime_get(rtd, cstream);
  	if (ret < 0)
  		goto pm_err;
4137f4b65   Cezary Rojewski   ASoC: compress: A...
81

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
82
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
1e57b8289   Charles Keepax   ASoC: compress: A...
83

b5ae4ccea   Kuninori Morimoto   ASoC: soc-dai: ad...
84
85
86
  	ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
  	if (ret < 0)
  		goto out;
1e57b8289   Charles Keepax   ASoC: compress: A...
87
88
89
90
  
  	ret = soc_compr_components_open(cstream, &component);
  	if (ret < 0)
  		goto machine_err;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
91

9ab711cb8   Kuninori Morimoto   ASoC: soc-link: a...
92
93
94
  	ret = snd_soc_link_compr_startup(cstream);
  	if (ret < 0)
  		goto machine_err;
1245b7005   Namarta Kohli   ASoC: add compres...
95

24894b764   Lars-Peter Clausen   ASoC: Add helper ...
96
  	snd_soc_runtime_activate(rtd, cstream->direction);
1245b7005   Namarta Kohli   ASoC: add compres...
97

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
98
  	mutex_unlock(&rtd->card->pcm_mutex);
15e2e6194   Charles Keepax   ASoC: soc-compres...
99

1245b7005   Namarta Kohli   ASoC: add compres...
100
101
102
  	return 0;
  
  machine_err:
1e57b8289   Charles Keepax   ASoC: compress: A...
103
  	soc_compr_components_free(cstream, component);
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
104

2b25f81d4   Kuninori Morimoto   ASoC: soc-dai: ad...
105
  	snd_soc_dai_compr_shutdown(cpu_dai, cstream);
1245b7005   Namarta Kohli   ASoC: add compres...
106
  out:
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
107
  	mutex_unlock(&rtd->card->pcm_mutex);
4137f4b65   Cezary Rojewski   ASoC: compress: A...
108
  pm_err:
939a5cfb2   Kuninori Morimoto   ASoC: soc-compone...
109
  	snd_soc_pcm_component_pm_runtime_put(rtd, cstream, 1);
4137f4b65   Cezary Rojewski   ASoC: compress: A...
110

1245b7005   Namarta Kohli   ASoC: add compres...
111
112
  	return ret;
  }
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
113
114
115
  static int soc_compr_open_fe(struct snd_compr_stream *cstream)
  {
  	struct snd_soc_pcm_runtime *fe = cstream->private_data;
01b8cedfd   Satish Babu Patakokila   ASoC: compress: D...
116
117
  	struct snd_pcm_substream *fe_substream =
  		 fe->pcm->streams[cstream->direction].substream;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
118
  	struct snd_soc_component *component;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
119
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
120
121
122
  	struct snd_soc_dpcm *dpcm;
  	struct snd_soc_dapm_widget_list *list;
  	int stream;
572e6c8dd   Charles Keepax   ASoC: compress: O...
123
  	int ret;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
124
125
126
127
128
129
130
  
  	if (cstream->direction == SND_COMPRESS_PLAYBACK)
  		stream = SNDRV_PCM_STREAM_PLAYBACK;
  	else
  		stream = SNDRV_PCM_STREAM_CAPTURE;
  
  	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
0b0722e19   Srinivas Kandagatla   ASoC: compress: m...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  	fe->dpcm[stream].runtime = fe_substream->runtime;
  
  	ret = dpcm_path_get(fe, stream, &list);
  	if (ret < 0)
  		goto be_err;
  	else if (ret == 0)
  		dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route
  ",
  			fe->dai_link->name, stream ? "capture" : "playback");
  	/* calculate valid and active FE <-> BE dpcms */
  	dpcm_process_paths(fe, stream, &list, 1);
  	fe->dpcm[stream].runtime = fe_substream->runtime;
  
  	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
  
  	ret = dpcm_be_dai_startup(fe, stream);
  	if (ret < 0) {
  		/* clean up all links */
8d6258a4d   Kuninori Morimoto   ASoC: add for_eac...
149
  		for_each_dpcm_be(fe, stream, dpcm)
0b0722e19   Srinivas Kandagatla   ASoC: compress: m...
150
151
152
153
154
155
  			dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
  
  		dpcm_be_disconnect(fe, stream);
  		fe->dpcm[stream].runtime = NULL;
  		goto out;
  	}
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
156

b5ae4ccea   Kuninori Morimoto   ASoC: soc-dai: ad...
157
158
159
  	ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
  	if (ret < 0)
  		goto out;
2e622ae41   Vinod Koul   ASoC: compress: A...
160

1e57b8289   Charles Keepax   ASoC: compress: A...
161
162
  	ret = soc_compr_components_open(cstream, &component);
  	if (ret < 0)
0b0722e19   Srinivas Kandagatla   ASoC: compress: m...
163
  		goto open_err;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
164

9ab711cb8   Kuninori Morimoto   ASoC: soc-link: a...
165
166
167
  	ret = snd_soc_link_compr_startup(cstream);
  	if (ret < 0)
  		goto machine_err;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
168

2a99ef0fd   Liam Girdwood   ASoC: compress: A...
169
170
171
172
173
  	dpcm_clear_pending_state(fe, stream);
  	dpcm_path_put(&list);
  
  	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
  	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
24894b764   Lars-Peter Clausen   ASoC: Add helper ...
174
  	snd_soc_runtime_activate(fe, stream);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
175
176
177
178
  
  	mutex_unlock(&fe->card->mutex);
  
  	return 0;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
179
  machine_err:
1e57b8289   Charles Keepax   ASoC: compress: A...
180
  	soc_compr_components_free(cstream, component);
0b0722e19   Srinivas Kandagatla   ASoC: compress: m...
181
  open_err:
2b25f81d4   Kuninori Morimoto   ASoC: soc-dai: ad...
182
  	snd_soc_dai_compr_shutdown(cpu_dai, cstream);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
183
  out:
0b0722e19   Srinivas Kandagatla   ASoC: compress: m...
184
185
  	dpcm_path_put(&list);
  be_err:
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
186
187
188
189
  	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
  	mutex_unlock(&fe->card->mutex);
  	return ret;
  }
1245b7005   Namarta Kohli   ASoC: add compres...
190
191
192
  static int soc_compr_free(struct snd_compr_stream *cstream)
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
193
194
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
  	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
939a5cfb2   Kuninori Morimoto   ASoC: soc-compone...
195
  	int stream;
1245b7005   Namarta Kohli   ASoC: add compres...
196

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
197
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
15e2e6194   Charles Keepax   ASoC: soc-compres...
198

24894b764   Lars-Peter Clausen   ASoC: Add helper ...
199
200
201
202
  	if (cstream->direction == SND_COMPRESS_PLAYBACK)
  		stream = SNDRV_PCM_STREAM_PLAYBACK;
  	else
  		stream = SNDRV_PCM_STREAM_CAPTURE;
1245b7005   Namarta Kohli   ASoC: add compres...
203

24894b764   Lars-Peter Clausen   ASoC: Add helper ...
204
  	snd_soc_runtime_deactivate(rtd, stream);
da18396f9   Mark Brown   ASoC: core: Allow...
205

24894b764   Lars-Peter Clausen   ASoC: Add helper ...
206
  	snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
1245b7005   Namarta Kohli   ASoC: add compres...
207

b3dea624b   Kuninori Morimoto   ASoC: use snd_soc...
208
  	if (!snd_soc_dai_active(cpu_dai))
1245b7005   Namarta Kohli   ASoC: add compres...
209
  		cpu_dai->rate = 0;
b3dea624b   Kuninori Morimoto   ASoC: use snd_soc...
210
  	if (!snd_soc_dai_active(codec_dai))
1245b7005   Namarta Kohli   ASoC: add compres...
211
  		codec_dai->rate = 0;
0e532c99b   Kuninori Morimoto   ASoC: soc-link: a...
212
  	snd_soc_link_compr_shutdown(cstream);
1245b7005   Namarta Kohli   ASoC: add compres...
213

1e57b8289   Charles Keepax   ASoC: compress: A...
214
  	soc_compr_components_free(cstream, NULL);
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
215

2b25f81d4   Kuninori Morimoto   ASoC: soc-dai: ad...
216
  	snd_soc_dai_compr_shutdown(cpu_dai, cstream);
2e622ae41   Vinod Koul   ASoC: compress: A...
217

3f4cf7979   Kuninori Morimoto   ASoC: soc-dapm: a...
218
  	snd_soc_dapm_stream_stop(rtd, stream);
1245b7005   Namarta Kohli   ASoC: add compres...
219

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
220
  	mutex_unlock(&rtd->card->pcm_mutex);
4137f4b65   Cezary Rojewski   ASoC: compress: A...
221

939a5cfb2   Kuninori Morimoto   ASoC: soc-compone...
222
  	snd_soc_pcm_component_pm_runtime_put(rtd, cstream, 0);
4137f4b65   Cezary Rojewski   ASoC: compress: A...
223

1245b7005   Namarta Kohli   ASoC: add compres...
224
225
  	return 0;
  }
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
226
227
228
  static int soc_compr_free_fe(struct snd_compr_stream *cstream)
  {
  	struct snd_soc_pcm_runtime *fe = cstream->private_data;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
229
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
230
231
232
233
  	struct snd_soc_dpcm *dpcm;
  	int stream, ret;
  
  	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
24894b764   Lars-Peter Clausen   ASoC: Add helper ...
234
  	if (cstream->direction == SND_COMPRESS_PLAYBACK)
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
235
  		stream = SNDRV_PCM_STREAM_PLAYBACK;
24894b764   Lars-Peter Clausen   ASoC: Add helper ...
236
  	else
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
237
  		stream = SNDRV_PCM_STREAM_CAPTURE;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
238

24894b764   Lars-Peter Clausen   ASoC: Add helper ...
239
  	snd_soc_runtime_deactivate(fe, stream);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
240
241
242
243
244
  
  	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
  
  	ret = dpcm_be_dai_hw_free(fe, stream);
  	if (ret < 0)
141dfc9e3   Charles Keepax   ASoC: compress: F...
245
246
  		dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d
  ", ret);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
247
248
249
250
  
  	ret = dpcm_be_dai_shutdown(fe, stream);
  
  	/* mark FE's links ready to prune */
8d6258a4d   Kuninori Morimoto   ASoC: add for_eac...
251
  	for_each_dpcm_be(fe, stream, dpcm)
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
252
  		dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1c5312308   Kuninori Morimoto   ASoC: soc-pcm/soc...
253
  	dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
254
255
256
257
258
259
260
  
  	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
  	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
  
  	dpcm_be_disconnect(fe, stream);
  
  	fe->dpcm[stream].runtime = NULL;
0e532c99b   Kuninori Morimoto   ASoC: soc-link: a...
261
  	snd_soc_link_compr_shutdown(cstream);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
262

1e57b8289   Charles Keepax   ASoC: compress: A...
263
  	soc_compr_components_free(cstream, NULL);
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
264

2b25f81d4   Kuninori Morimoto   ASoC: soc-dai: ad...
265
  	snd_soc_dai_compr_shutdown(cpu_dai, cstream);
2e622ae41   Vinod Koul   ASoC: compress: A...
266

2a99ef0fd   Liam Girdwood   ASoC: compress: A...
267
268
269
  	mutex_unlock(&fe->card->mutex);
  	return 0;
  }
4ef0ecb80   Charles Keepax   ASoC: compress: A...
270
271
  static int soc_compr_components_trigger(struct snd_compr_stream *cstream,
  					int cmd)
1245b7005   Namarta Kohli   ASoC: add compres...
272
  {
1245b7005   Namarta Kohli   ASoC: add compres...
273
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
274
  	struct snd_soc_component *component;
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
275
  	int i, ret;
15e2e6194   Charles Keepax   ASoC: soc-compres...
276

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
277
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
278
279
280
281
282
283
284
285
286
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->trigger)
  			continue;
  
  		ret = component->driver->compress_ops->trigger(
  			component, cstream, cmd);
  		if (ret < 0)
  			return ret;
  	}
4ef0ecb80   Charles Keepax   ASoC: compress: A...
287
288
289
290
291
292
  	return 0;
  }
  
  static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
293
294
  	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
4ef0ecb80   Charles Keepax   ASoC: compress: A...
295
  	int ret;
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
296
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
4ef0ecb80   Charles Keepax   ASoC: compress: A...
297
298
299
300
  
  	ret = soc_compr_components_trigger(cstream, cmd);
  	if (ret < 0)
  		goto out;
eb08411bd   Kuninori Morimoto   ASoC: soc-dai: ad...
301
302
303
  	ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
  	if (ret < 0)
  		goto out;
2e622ae41   Vinod Koul   ASoC: compress: A...
304

da18396f9   Mark Brown   ASoC: core: Allow...
305
306
307
308
309
310
311
  	switch (cmd) {
  	case SNDRV_PCM_TRIGGER_START:
  		snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
  		break;
  	case SNDRV_PCM_TRIGGER_STOP:
  		snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
  		break;
e38b9b747   Mark Brown   ASoC: compress: O...
312
  	}
1245b7005   Namarta Kohli   ASoC: add compres...
313

15e2e6194   Charles Keepax   ASoC: soc-compres...
314
  out:
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
315
  	mutex_unlock(&rtd->card->pcm_mutex);
1245b7005   Namarta Kohli   ASoC: add compres...
316
317
  	return ret;
  }
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
318
319
320
  static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
  {
  	struct snd_soc_pcm_runtime *fe = cstream->private_data;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
321
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
52cadf1fd   Charles Keepax   ASoC: compress: C...
322
  	int ret, stream;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
323
324
  
  	if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
4ef0ecb80   Charles Keepax   ASoC: compress: A...
325
326
  	    cmd == SND_COMPR_TRIGGER_DRAIN)
  		return soc_compr_components_trigger(cstream, cmd);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
327
328
329
330
331
  
  	if (cstream->direction == SND_COMPRESS_PLAYBACK)
  		stream = SNDRV_PCM_STREAM_PLAYBACK;
  	else
  		stream = SNDRV_PCM_STREAM_CAPTURE;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
332
  	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
eb08411bd   Kuninori Morimoto   ASoC: soc-dai: ad...
333
334
335
  	ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
  	if (ret < 0)
  		goto out;
2e622ae41   Vinod Koul   ASoC: compress: A...
336

4ef0ecb80   Charles Keepax   ASoC: compress: A...
337
338
339
  	ret = soc_compr_components_trigger(cstream, cmd);
  	if (ret < 0)
  		goto out;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
340

2a99ef0fd   Liam Girdwood   ASoC: compress: A...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
  	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
  
  	ret = dpcm_be_dai_trigger(fe, stream, cmd);
  
  	switch (cmd) {
  	case SNDRV_PCM_TRIGGER_START:
  	case SNDRV_PCM_TRIGGER_RESUME:
  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
  		break;
  	case SNDRV_PCM_TRIGGER_STOP:
  	case SNDRV_PCM_TRIGGER_SUSPEND:
  		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
  		break;
  	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
  		break;
  	}
  
  out:
  	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
  	mutex_unlock(&fe->card->mutex);
  	return ret;
  }
4ef0ecb80   Charles Keepax   ASoC: compress: A...
365
366
  static int soc_compr_components_set_params(struct snd_compr_stream *cstream,
  					   struct snd_compr_params *params)
1245b7005   Namarta Kohli   ASoC: add compres...
367
368
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
369
  	struct snd_soc_component *component;
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
370
  	int i, ret;
4ef0ecb80   Charles Keepax   ASoC: compress: A...
371

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
372
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
373
374
375
376
377
378
379
380
381
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->set_params)
  			continue;
  
  		ret = component->driver->compress_ops->set_params(
  			component, cstream, params);
  		if (ret < 0)
  			return ret;
  	}
4ef0ecb80   Charles Keepax   ASoC: compress: A...
382
383
384
385
386
387
388
  	return 0;
  }
  
  static int soc_compr_set_params(struct snd_compr_stream *cstream,
  				struct snd_compr_params *params)
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
389
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
52cadf1fd   Charles Keepax   ASoC: compress: C...
390
  	int ret;
1245b7005   Namarta Kohli   ASoC: add compres...
391

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
392
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
15e2e6194   Charles Keepax   ASoC: soc-compres...
393

ef050bece   Charles Keepax   ASoC: Remove plat...
394
395
396
397
398
399
  	/*
  	 * First we call set_params for the CPU DAI, then the component
  	 * driver this should configure the SoC side. If the machine has
  	 * compressed ops then we call that as well. The expectation is
  	 * that these callbacks will configure everything for this compress
  	 * path, like configuring a PCM port for a CODEC.
1245b7005   Namarta Kohli   ASoC: add compres...
400
  	 */
8dfedafb5   Kuninori Morimoto   ASoC: soc-dai: ad...
401
402
403
  	ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
  	if (ret < 0)
  		goto err;
2e622ae41   Vinod Koul   ASoC: compress: A...
404

4ef0ecb80   Charles Keepax   ASoC: compress: A...
405
406
407
  	ret = soc_compr_components_set_params(cstream, params);
  	if (ret < 0)
  		goto err;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
408

eab810f37   Kuninori Morimoto   ASoC: soc-link: a...
409
410
411
  	ret = snd_soc_link_compr_set_params(cstream);
  	if (ret < 0)
  		goto err;
1245b7005   Namarta Kohli   ASoC: add compres...
412

2c071ed7c   Charles Keepax   ASoC: soc-compres...
413
414
  	if (cstream->direction == SND_COMPRESS_PLAYBACK)
  		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
89027d9eb   Charles Keepax   ASoC: compress: F...
415
  					  SND_SOC_DAPM_STREAM_START);
2c071ed7c   Charles Keepax   ASoC: soc-compres...
416
417
  	else
  		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
89027d9eb   Charles Keepax   ASoC: compress: F...
418
  					  SND_SOC_DAPM_STREAM_START);
1245b7005   Namarta Kohli   ASoC: add compres...
419

fa40ef208   Charles Keepax   ASoC: compress: C...
420
421
  	/* cancel any delayed stream shutdown that is pending */
  	rtd->pop_wait = 0;
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
422
  	mutex_unlock(&rtd->card->pcm_mutex);
fa40ef208   Charles Keepax   ASoC: compress: C...
423
424
  
  	cancel_delayed_work_sync(&rtd->delayed_work);
52cadf1fd   Charles Keepax   ASoC: compress: C...
425
  	return 0;
fa40ef208   Charles Keepax   ASoC: compress: C...
426
427
  
  err:
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
428
  	mutex_unlock(&rtd->card->pcm_mutex);
1245b7005   Namarta Kohli   ASoC: add compres...
429
430
  	return ret;
  }
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
431
  static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
89027d9eb   Charles Keepax   ASoC: compress: F...
432
  				   struct snd_compr_params *params)
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
433
434
  {
  	struct snd_soc_pcm_runtime *fe = cstream->private_data;
01b8cedfd   Satish Babu Patakokila   ASoC: compress: D...
435
436
  	struct snd_pcm_substream *fe_substream =
  		 fe->pcm->streams[cstream->direction].substream;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
437
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
52cadf1fd   Charles Keepax   ASoC: compress: C...
438
  	int ret, stream;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
439
440
441
442
443
444
445
  
  	if (cstream->direction == SND_COMPRESS_PLAYBACK)
  		stream = SNDRV_PCM_STREAM_PLAYBACK;
  	else
  		stream = SNDRV_PCM_STREAM_CAPTURE;
  
  	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
0b0722e19   Srinivas Kandagatla   ASoC: compress: m...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
  	/*
  	 * Create an empty hw_params for the BE as the machine driver must
  	 * fix this up to match DSP decoder and ASRC configuration.
  	 * I.e. machine driver fixup for compressed BE is mandatory.
  	 */
  	memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
  		sizeof(struct snd_pcm_hw_params));
  
  	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
  
  	ret = dpcm_be_dai_hw_params(fe, stream);
  	if (ret < 0)
  		goto out;
  
  	ret = dpcm_be_dai_prepare(fe, stream);
  	if (ret < 0)
  		goto out;
8dfedafb5   Kuninori Morimoto   ASoC: soc-dai: ad...
463
464
465
  	ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
  	if (ret < 0)
  		goto out;
2e622ae41   Vinod Koul   ASoC: compress: A...
466

4ef0ecb80   Charles Keepax   ASoC: compress: A...
467
468
469
  	ret = soc_compr_components_set_params(cstream, params);
  	if (ret < 0)
  		goto out;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
470

eab810f37   Kuninori Morimoto   ASoC: soc-link: a...
471
472
473
  	ret = snd_soc_link_compr_set_params(cstream);
  	if (ret < 0)
  		goto out;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
474

15f6b09a0   Daniel Mack   ASoC: soc-compres...
475
  	dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
476
477
478
479
480
481
482
  	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
  
  out:
  	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
  	mutex_unlock(&fe->card->mutex);
  	return ret;
  }
1245b7005   Namarta Kohli   ASoC: add compres...
483
  static int soc_compr_get_params(struct snd_compr_stream *cstream,
89027d9eb   Charles Keepax   ASoC: compress: F...
484
  				struct snd_codec *params)
1245b7005   Namarta Kohli   ASoC: add compres...
485
486
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
487
  	struct snd_soc_component *component;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
488
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
489
  	int i, ret = 0;
1245b7005   Namarta Kohli   ASoC: add compres...
490

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
491
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
15e2e6194   Charles Keepax   ASoC: soc-compres...
492

adbef5432   Kuninori Morimoto   ASoC: soc-dai: ad...
493
494
495
  	ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params);
  	if (ret < 0)
  		goto err;
2e622ae41   Vinod Koul   ASoC: compress: A...
496

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
497
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
498
499
500
501
502
503
504
505
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->get_params)
  			continue;
  
  		ret = component->driver->compress_ops->get_params(
  			component, cstream, params);
  		break;
  	}
2e622ae41   Vinod Koul   ASoC: compress: A...
506
  err:
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
507
  	mutex_unlock(&rtd->card->pcm_mutex);
1245b7005   Namarta Kohli   ASoC: add compres...
508
509
510
511
  	return ret;
  }
  
  static int soc_compr_get_caps(struct snd_compr_stream *cstream,
89027d9eb   Charles Keepax   ASoC: compress: F...
512
  			      struct snd_compr_caps *caps)
1245b7005   Namarta Kohli   ASoC: add compres...
513
514
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
515
  	struct snd_soc_component *component;
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
516
  	int i, ret = 0;
1245b7005   Namarta Kohli   ASoC: add compres...
517

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
518
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
15e2e6194   Charles Keepax   ASoC: soc-compres...
519

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
520
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
521
522
523
524
525
526
527
528
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->get_caps)
  			continue;
  
  		ret = component->driver->compress_ops->get_caps(
  			component, cstream, caps);
  		break;
  	}
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
529
  	mutex_unlock(&rtd->card->pcm_mutex);
1245b7005   Namarta Kohli   ASoC: add compres...
530
531
532
533
  	return ret;
  }
  
  static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
89027d9eb   Charles Keepax   ASoC: compress: F...
534
  				    struct snd_compr_codec_caps *codec)
1245b7005   Namarta Kohli   ASoC: add compres...
535
536
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
537
  	struct snd_soc_component *component;
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
538
  	int i, ret = 0;
1245b7005   Namarta Kohli   ASoC: add compres...
539

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
540
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
15e2e6194   Charles Keepax   ASoC: soc-compres...
541

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
542
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
543
544
545
546
547
548
549
550
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->get_codec_caps)
  			continue;
  
  		ret = component->driver->compress_ops->get_codec_caps(
  			component, cstream, codec);
  		break;
  	}
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
551
  	mutex_unlock(&rtd->card->pcm_mutex);
1245b7005   Namarta Kohli   ASoC: add compres...
552
553
554
555
556
557
  	return ret;
  }
  
  static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
558
  	struct snd_soc_component *component;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
559
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
560
  	int i, ret = 0;
1245b7005   Namarta Kohli   ASoC: add compres...
561

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
562
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
15e2e6194   Charles Keepax   ASoC: soc-compres...
563

53294353a   Kuninori Morimoto   ASoC: soc-dai: ad...
564
565
566
  	ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes);
  	if (ret < 0)
  		goto err;
2e622ae41   Vinod Koul   ASoC: compress: A...
567

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
568
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
569
570
571
572
573
574
575
576
577
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->ack)
  			continue;
  
  		ret = component->driver->compress_ops->ack(
  			component, cstream, bytes);
  		if (ret < 0)
  			goto err;
  	}
2e622ae41   Vinod Koul   ASoC: compress: A...
578
  err:
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
579
  	mutex_unlock(&rtd->card->pcm_mutex);
1245b7005   Namarta Kohli   ASoC: add compres...
580
581
582
583
  	return ret;
  }
  
  static int soc_compr_pointer(struct snd_compr_stream *cstream,
89027d9eb   Charles Keepax   ASoC: compress: F...
584
  			     struct snd_compr_tstamp *tstamp)
1245b7005   Namarta Kohli   ASoC: add compres...
585
586
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
587
  	struct snd_soc_component *component;
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
588
  	int i, ret = 0;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
589
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
1245b7005   Namarta Kohli   ASoC: add compres...
590

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
591
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
15e2e6194   Charles Keepax   ASoC: soc-compres...
592

ed38cc590   Kuninori Morimoto   ASoC: soc-dai: ad...
593
594
595
  	ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp);
  	if (ret < 0)
  		goto out;
2e622ae41   Vinod Koul   ASoC: compress: A...
596

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
597
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
598
599
600
601
602
603
604
605
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->pointer)
  			continue;
  
  		ret = component->driver->compress_ops->pointer(
  			component, cstream, tstamp);
  		break;
  	}
ed38cc590   Kuninori Morimoto   ASoC: soc-dai: ad...
606
  out:
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
607
  	mutex_unlock(&rtd->card->pcm_mutex);
7c9190f7e   Charles Keepax   ASoC: compress: P...
608
  	return ret;
1245b7005   Namarta Kohli   ASoC: add compres...
609
  }
1f88eb0f0   Charles Keepax   ASoC: soc-compres...
610
  static int soc_compr_copy(struct snd_compr_stream *cstream,
4daf891cd   Charles Keepax   ALSA: compress_co...
611
  			  char __user *buf, size_t count)
1f88eb0f0   Charles Keepax   ASoC: soc-compres...
612
613
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
614
  	struct snd_soc_component *component;
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
615
  	int i, ret = 0;
1f88eb0f0   Charles Keepax   ASoC: soc-compres...
616

72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
617
  	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
1f88eb0f0   Charles Keepax   ASoC: soc-compres...
618

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
619
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
620
621
622
623
624
625
626
627
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->copy)
  			continue;
  
  		ret = component->driver->compress_ops->copy(
  			component, cstream, buf, count);
  		break;
  	}
72b745e3a   Peter Ujfalusi   ASoC: core: Move ...
628
  	mutex_unlock(&rtd->card->pcm_mutex);
1f88eb0f0   Charles Keepax   ASoC: soc-compres...
629
630
  	return ret;
  }
02bd90e86   Vinod Koul   ASoC: compress: u...
631
  static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
89027d9eb   Charles Keepax   ASoC: compress: F...
632
  				  struct snd_compr_metadata *metadata)
36953d981   Jeeja KP   ASoC: compress - ...
633
634
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
635
  	struct snd_soc_component *component;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
636
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
637
  	int i, ret;
36953d981   Jeeja KP   ASoC: compress - ...
638

88b3a7dfe   Kuninori Morimoto   ASoC: soc-dai: ad...
639
640
641
  	ret = snd_soc_dai_compr_set_metadata(cpu_dai, cstream, metadata);
  	if (ret < 0)
  		return ret;
2e622ae41   Vinod Koul   ASoC: compress: A...
642

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
643
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
644
645
646
647
648
649
650
651
652
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->set_metadata)
  			continue;
  
  		ret = component->driver->compress_ops->set_metadata(
  			component, cstream, metadata);
  		if (ret < 0)
  			return ret;
  	}
52cadf1fd   Charles Keepax   ASoC: compress: C...
653
  	return 0;
36953d981   Jeeja KP   ASoC: compress - ...
654
  }
02bd90e86   Vinod Koul   ASoC: compress: u...
655
  static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
89027d9eb   Charles Keepax   ASoC: compress: F...
656
  				  struct snd_compr_metadata *metadata)
36953d981   Jeeja KP   ASoC: compress - ...
657
658
  {
  	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
659
  	struct snd_soc_component *component;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
660
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
661
  	int i, ret;
36953d981   Jeeja KP   ASoC: compress - ...
662

94d728199   Kuninori Morimoto   ASoC: soc-dai: ad...
663
664
665
  	ret = snd_soc_dai_compr_get_metadata(cpu_dai, cstream, metadata);
  	if (ret < 0)
  		return ret;
2e622ae41   Vinod Koul   ASoC: compress: A...
666

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
667
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
668
669
670
671
672
673
674
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->get_metadata)
  			continue;
  
  		return component->driver->compress_ops->get_metadata(
  			component, cstream, metadata);
  	}
52cadf1fd   Charles Keepax   ASoC: compress: C...
675
  	return 0;
36953d981   Jeeja KP   ASoC: compress - ...
676
  }
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
677

1245b7005   Namarta Kohli   ASoC: add compres...
678
679
680
681
682
  /* ASoC Compress operations */
  static struct snd_compr_ops soc_compr_ops = {
  	.open		= soc_compr_open,
  	.free		= soc_compr_free,
  	.set_params	= soc_compr_set_params,
02bd90e86   Vinod Koul   ASoC: compress: u...
683
684
  	.set_metadata   = soc_compr_set_metadata,
  	.get_metadata	= soc_compr_get_metadata,
1245b7005   Namarta Kohli   ASoC: add compres...
685
686
687
688
689
690
691
  	.get_params	= soc_compr_get_params,
  	.trigger	= soc_compr_trigger,
  	.pointer	= soc_compr_pointer,
  	.ack		= soc_compr_ack,
  	.get_caps	= soc_compr_get_caps,
  	.get_codec_caps = soc_compr_get_codec_caps
  };
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
692
693
694
695
696
697
698
699
700
701
702
703
704
705
  /* ASoC Dynamic Compress operations */
  static struct snd_compr_ops soc_compr_dyn_ops = {
  	.open		= soc_compr_open_fe,
  	.free		= soc_compr_free_fe,
  	.set_params	= soc_compr_set_params_fe,
  	.get_params	= soc_compr_get_params,
  	.set_metadata   = soc_compr_set_metadata,
  	.get_metadata	= soc_compr_get_metadata,
  	.trigger	= soc_compr_trigger_fe,
  	.pointer	= soc_compr_pointer,
  	.ack		= soc_compr_ack,
  	.get_caps	= soc_compr_get_caps,
  	.get_codec_caps = soc_compr_get_codec_caps
  };
6f0c42269   Jie Yang   ASoC: compress: a...
706
707
708
709
710
711
712
713
714
  /**
   * 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)
1245b7005   Namarta Kohli   ASoC: add compres...
715
  {
9e7e3738a   Kuninori Morimoto   ASoC: snd_soc_com...
716
  	struct snd_soc_component *component;
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
717
718
  	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
  	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
1245b7005   Namarta Kohli   ASoC: add compres...
719
  	struct snd_compr *compr;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
720
  	struct snd_pcm *be_pcm;
1245b7005   Namarta Kohli   ASoC: add compres...
721
722
  	char new_name[64];
  	int ret = 0, direction = 0;
a10680458   Vinod Koul   ASoC: compress: F...
723
  	int playback = 0, capture = 0;
613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
724
  	int i;
1245b7005   Namarta Kohli   ASoC: add compres...
725

6e1276a5e   Bard Liao   ASoC: Return erro...
726
727
  	if (rtd->num_cpus > 1 ||
  	    rtd->num_codecs > 1) {
141dfc9e3   Charles Keepax   ASoC: compress: F...
728
  		dev_err(rtd->card->dev,
6e1276a5e   Bard Liao   ASoC: Return erro...
729
730
  			"Compress ASoC: Multi CPU/Codec not supported
  ");
8151d5e60   Benoit Cousson   ASoC: compress: P...
731
732
  		return -EINVAL;
  	}
1245b7005   Namarta Kohli   ASoC: add compres...
733
  	/* check client and interface hw capabilities */
467fece8f   Kuninori Morimoto   ASoC: soc-dai: mo...
734
735
  	if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
  	    snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_PLAYBACK))
a10680458   Vinod Koul   ASoC: compress: F...
736
  		playback = 1;
467fece8f   Kuninori Morimoto   ASoC: soc-dai: mo...
737
738
  	if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
  	    snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_CAPTURE))
a10680458   Vinod Koul   ASoC: compress: F...
739
  		capture = 1;
a10680458   Vinod Koul   ASoC: compress: F...
740
741
742
743
744
  	/*
  	 * Compress devices are unidirectional so only one of the directions
  	 * should be set, check for that (xor)
  	 */
  	if (playback + capture != 1) {
141dfc9e3   Charles Keepax   ASoC: compress: F...
745
746
747
748
  		dev_err(rtd->card->dev,
  			"Compress ASoC: Invalid direction for P %d, C %d
  ",
  			playback, capture);
a10680458   Vinod Koul   ASoC: compress: F...
749
750
  		return -EINVAL;
  	}
aeb6fa0f1   Peng Donglin   ASoC: compress: S...
751
  	if (playback)
daa2db59c   Charles Keepax   ASoC: soc-compres...
752
  		direction = SND_COMPRESS_PLAYBACK;
daa2db59c   Charles Keepax   ASoC: soc-compres...
753
  	else
a10680458   Vinod Koul   ASoC: compress: F...
754
  		direction = SND_COMPRESS_CAPTURE;
daa2db59c   Charles Keepax   ASoC: soc-compres...
755

09f448a41   Amadeusz Sławiński   ASoC: compress: F...
756
  	compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL);
7a0cf42ed   Markus Elfring   ASoC: compress: D...
757
  	if (!compr)
1245b7005   Namarta Kohli   ASoC: add compres...
758
  		return -ENOMEM;
1245b7005   Namarta Kohli   ASoC: add compres...
759

1f88eb0f0   Charles Keepax   ASoC: soc-compres...
760
761
  	compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
  				  GFP_KERNEL);
09f448a41   Amadeusz Sławiński   ASoC: compress: F...
762
763
  	if (!compr->ops)
  		return -ENOMEM;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
764
765
766
767
768
769
  
  	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,
d3268a40d   Qais Yousef   ASoC: soc-compres...
770
771
  				rtd->dai_link->dpcm_playback,
  				rtd->dai_link->dpcm_capture, &be_pcm);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
772
  		if (ret < 0) {
141dfc9e3   Charles Keepax   ASoC: compress: F...
773
774
775
776
  			dev_err(rtd->card->dev,
  				"Compress ASoC: can't create compressed for %s: %d
  ",
  				rtd->dai_link->name, ret);
09f448a41   Amadeusz Sławiński   ASoC: compress: F...
777
  			return ret;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
778
779
780
781
  		}
  
  		rtd->pcm = be_pcm;
  		rtd->fe_compr = 1;
d3268a40d   Qais Yousef   ASoC: soc-compres...
782
783
784
785
  		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;
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
786
  		memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
aeb6fa0f1   Peng Donglin   ASoC: compress: S...
787
788
789
  	} else {
  		snprintf(new_name, sizeof(new_name), "%s %s-%d",
  			rtd->dai_link->stream_name, codec_dai->name, num);
2a99ef0fd   Liam Girdwood   ASoC: compress: A...
790
  		memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
aeb6fa0f1   Peng Donglin   ASoC: compress: S...
791
  	}
1f88eb0f0   Charles Keepax   ASoC: soc-compres...
792

613fb5005   Kuninori Morimoto   ASoC: soc-core: r...
793
  	for_each_rtd_components(rtd, i, component) {
c6cb522c1   Kuninori Morimoto   ASoC: soc-compres...
794
795
796
797
798
799
800
  		if (!component->driver->compress_ops ||
  		    !component->driver->compress_ops->copy)
  			continue;
  
  		compr->ops->copy = soc_compr_copy;
  		break;
  	}
1245b7005   Namarta Kohli   ASoC: add compres...
801
  	mutex_init(&compr->lock);
e5241a8c4   Richard Fitzgerald   ALSA: compress: P...
802
803
  	ret = snd_compress_new(rtd->card->snd_card, num, direction,
  				new_name, compr);
1245b7005   Namarta Kohli   ASoC: add compres...
804
  	if (ret < 0) {
c2233a266   Kuninori Morimoto   ASoC: soc: use as...
805
  		component = asoc_rtd_to_codec(rtd, 0)->component;
141dfc9e3   Charles Keepax   ASoC: compress: F...
806
807
808
809
  		dev_err(component->dev,
  			"Compress ASoC: can't create compress for codec %s: %d
  ",
  			component->name, ret);
09f448a41   Amadeusz Sławiński   ASoC: compress: F...
810
  		return ret;
1245b7005   Namarta Kohli   ASoC: add compres...
811
  	}
202c8f708   Charles Keepax   ASoC: soc-compres...
812
  	/* DAPM dai link stream work */
83f94a2e2   Kuninori Morimoto   ASoC: soc-core: a...
813
  	rtd->close_delayed_work_func = snd_soc_close_delayed_work;
202c8f708   Charles Keepax   ASoC: soc-compres...
814

1245b7005   Namarta Kohli   ASoC: add compres...
815
816
  	rtd->compr = compr;
  	compr->private_data = rtd;
1d5cd5254   Pierre-Louis Bossart   ASoC: soc-pcm/com...
817
818
819
  	dev_dbg(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok
  ",
  		codec_dai->name, cpu_dai->name);
1f88eb0f0   Charles Keepax   ASoC: soc-compres...
820

09f448a41   Amadeusz Sławiński   ASoC: compress: F...
821
  	return 0;
1245b7005   Namarta Kohli   ASoC: add compres...
822
  }
6f0c42269   Jie Yang   ASoC: compress: a...
823
  EXPORT_SYMBOL_GPL(snd_soc_new_compress);