0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/kernel.h>
0012 #include <linux/init.h>
0013 #include <linux/delay.h>
0014 #include <linux/slab.h>
0015 #include <linux/workqueue.h>
0016 #include <sound/core.h>
0017 #include <sound/compress_params.h>
0018 #include <sound/compress_driver.h>
0019 #include <sound/soc.h>
0020 #include <sound/initval.h>
0021 #include <sound/soc-dpcm.h>
0022 #include <sound/soc-link.h>
0023 #include <linux/pm_runtime.h>
0024
0025 static int snd_soc_compr_components_open(struct snd_compr_stream *cstream)
0026 {
0027 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0028 struct snd_soc_component *component;
0029 int ret = 0;
0030 int i;
0031
0032 for_each_rtd_components(rtd, i, component) {
0033 ret = snd_soc_component_module_get_when_open(component, cstream);
0034 if (ret < 0)
0035 break;
0036
0037 ret = snd_soc_component_compr_open(component, cstream);
0038 if (ret < 0)
0039 break;
0040 }
0041
0042 return ret;
0043 }
0044
0045 static void snd_soc_compr_components_free(struct snd_compr_stream *cstream,
0046 int rollback)
0047 {
0048 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0049 struct snd_soc_component *component;
0050 int i;
0051
0052 for_each_rtd_components(rtd, i, component) {
0053 snd_soc_component_compr_free(component, cstream, rollback);
0054 snd_soc_component_module_put_when_close(component, cstream, rollback);
0055 }
0056 }
0057
0058 static int soc_compr_clean(struct snd_compr_stream *cstream, int rollback)
0059 {
0060 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0061 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0062 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0063 int stream = cstream->direction;
0064
0065 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
0066
0067 if (!rollback)
0068 snd_soc_runtime_deactivate(rtd, stream);
0069
0070 snd_soc_dai_digital_mute(codec_dai, 1, stream);
0071
0072 if (!snd_soc_dai_active(cpu_dai))
0073 cpu_dai->rate = 0;
0074
0075 if (!snd_soc_dai_active(codec_dai))
0076 codec_dai->rate = 0;
0077
0078 snd_soc_link_compr_shutdown(cstream, rollback);
0079
0080 snd_soc_compr_components_free(cstream, rollback);
0081
0082 snd_soc_dai_compr_shutdown(cpu_dai, cstream, rollback);
0083
0084 if (!rollback)
0085 snd_soc_dapm_stream_stop(rtd, stream);
0086
0087 mutex_unlock(&rtd->card->pcm_mutex);
0088
0089 snd_soc_pcm_component_pm_runtime_put(rtd, cstream, rollback);
0090
0091 return 0;
0092 }
0093
0094 static int soc_compr_free(struct snd_compr_stream *cstream)
0095 {
0096 return soc_compr_clean(cstream, 0);
0097 }
0098
0099 static int soc_compr_open(struct snd_compr_stream *cstream)
0100 {
0101 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0102 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0103 int stream = cstream->direction;
0104 int ret;
0105
0106 ret = snd_soc_pcm_component_pm_runtime_get(rtd, cstream);
0107 if (ret < 0)
0108 goto err_no_lock;
0109
0110 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
0111
0112 ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
0113 if (ret < 0)
0114 goto err;
0115
0116 ret = snd_soc_compr_components_open(cstream);
0117 if (ret < 0)
0118 goto err;
0119
0120 ret = snd_soc_link_compr_startup(cstream);
0121 if (ret < 0)
0122 goto err;
0123
0124 snd_soc_runtime_activate(rtd, stream);
0125 err:
0126 mutex_unlock(&rtd->card->pcm_mutex);
0127 err_no_lock:
0128 if (ret < 0)
0129 soc_compr_clean(cstream, 1);
0130
0131 return ret;
0132 }
0133
0134 static int soc_compr_open_fe(struct snd_compr_stream *cstream)
0135 {
0136 struct snd_soc_pcm_runtime *fe = cstream->private_data;
0137 struct snd_pcm_substream *fe_substream =
0138 fe->pcm->streams[cstream->direction].substream;
0139 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
0140 struct snd_soc_dpcm *dpcm;
0141 struct snd_soc_dapm_widget_list *list;
0142 int stream = cstream->direction;
0143 int ret;
0144
0145 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
0146 fe->dpcm[stream].runtime = fe_substream->runtime;
0147
0148 ret = dpcm_path_get(fe, stream, &list);
0149 if (ret < 0)
0150 goto be_err;
0151
0152
0153 dpcm_process_paths(fe, stream, &list, 1);
0154 fe->dpcm[stream].runtime = fe_substream->runtime;
0155
0156 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
0157
0158 ret = dpcm_be_dai_startup(fe, stream);
0159 if (ret < 0) {
0160
0161 for_each_dpcm_be(fe, stream, dpcm)
0162 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
0163
0164 dpcm_be_disconnect(fe, stream);
0165 fe->dpcm[stream].runtime = NULL;
0166 goto out;
0167 }
0168
0169 ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
0170 if (ret < 0)
0171 goto out;
0172
0173 ret = snd_soc_compr_components_open(cstream);
0174 if (ret < 0)
0175 goto open_err;
0176
0177 ret = snd_soc_link_compr_startup(cstream);
0178 if (ret < 0)
0179 goto machine_err;
0180
0181 dpcm_clear_pending_state(fe, stream);
0182 dpcm_path_put(&list);
0183
0184 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
0185 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
0186
0187 mutex_lock_nested(&fe->card->pcm_mutex, fe->card->pcm_subclass);
0188 snd_soc_runtime_activate(fe, stream);
0189 mutex_unlock(&fe->card->pcm_mutex);
0190
0191 mutex_unlock(&fe->card->mutex);
0192
0193 return 0;
0194
0195 machine_err:
0196 snd_soc_compr_components_free(cstream, 1);
0197 open_err:
0198 snd_soc_dai_compr_shutdown(cpu_dai, cstream, 1);
0199 out:
0200 dpcm_path_put(&list);
0201 be_err:
0202 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
0203 mutex_unlock(&fe->card->mutex);
0204 return ret;
0205 }
0206
0207 static int soc_compr_free_fe(struct snd_compr_stream *cstream)
0208 {
0209 struct snd_soc_pcm_runtime *fe = cstream->private_data;
0210 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
0211 struct snd_soc_dpcm *dpcm;
0212 int stream = cstream->direction;
0213
0214 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
0215
0216 mutex_lock_nested(&fe->card->pcm_mutex, fe->card->pcm_subclass);
0217 snd_soc_runtime_deactivate(fe, stream);
0218 mutex_unlock(&fe->card->pcm_mutex);
0219
0220 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
0221
0222 dpcm_be_dai_hw_free(fe, stream);
0223
0224 dpcm_be_dai_shutdown(fe, stream);
0225
0226
0227 for_each_dpcm_be(fe, stream, dpcm)
0228 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
0229
0230 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
0231
0232 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
0233 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
0234
0235 dpcm_be_disconnect(fe, stream);
0236
0237 fe->dpcm[stream].runtime = NULL;
0238
0239 snd_soc_link_compr_shutdown(cstream, 0);
0240
0241 snd_soc_compr_components_free(cstream, 0);
0242
0243 snd_soc_dai_compr_shutdown(cpu_dai, cstream, 0);
0244
0245 mutex_unlock(&fe->card->mutex);
0246 return 0;
0247 }
0248
0249 static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
0250 {
0251 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0252 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0253 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0254 int stream = cstream->direction;
0255 int ret;
0256
0257 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
0258
0259 ret = snd_soc_component_compr_trigger(cstream, cmd);
0260 if (ret < 0)
0261 goto out;
0262
0263 ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
0264 if (ret < 0)
0265 goto out;
0266
0267 switch (cmd) {
0268 case SNDRV_PCM_TRIGGER_START:
0269 snd_soc_dai_digital_mute(codec_dai, 0, stream);
0270 break;
0271 case SNDRV_PCM_TRIGGER_STOP:
0272 snd_soc_dai_digital_mute(codec_dai, 1, stream);
0273 break;
0274 }
0275
0276 out:
0277 mutex_unlock(&rtd->card->pcm_mutex);
0278 return ret;
0279 }
0280
0281 static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
0282 {
0283 struct snd_soc_pcm_runtime *fe = cstream->private_data;
0284 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
0285 int stream = cstream->direction;
0286 int ret;
0287
0288 if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
0289 cmd == SND_COMPR_TRIGGER_DRAIN)
0290 return snd_soc_component_compr_trigger(cstream, cmd);
0291
0292 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
0293
0294 ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
0295 if (ret < 0)
0296 goto out;
0297
0298 ret = snd_soc_component_compr_trigger(cstream, cmd);
0299 if (ret < 0)
0300 goto out;
0301
0302 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
0303
0304 ret = dpcm_be_dai_trigger(fe, stream, cmd);
0305
0306 switch (cmd) {
0307 case SNDRV_PCM_TRIGGER_START:
0308 case SNDRV_PCM_TRIGGER_RESUME:
0309 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0310 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
0311 break;
0312 case SNDRV_PCM_TRIGGER_STOP:
0313 case SNDRV_PCM_TRIGGER_SUSPEND:
0314 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
0315 break;
0316 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0317 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
0318 break;
0319 }
0320
0321 out:
0322 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
0323 mutex_unlock(&fe->card->mutex);
0324 return ret;
0325 }
0326
0327 static int soc_compr_set_params(struct snd_compr_stream *cstream,
0328 struct snd_compr_params *params)
0329 {
0330 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0331 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0332 int stream = cstream->direction;
0333 int ret;
0334
0335 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
0336
0337
0338
0339
0340
0341
0342
0343
0344 ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
0345 if (ret < 0)
0346 goto err;
0347
0348 ret = snd_soc_component_compr_set_params(cstream, params);
0349 if (ret < 0)
0350 goto err;
0351
0352 ret = snd_soc_link_compr_set_params(cstream);
0353 if (ret < 0)
0354 goto err;
0355
0356 snd_soc_dapm_stream_event(rtd, stream, SND_SOC_DAPM_STREAM_START);
0357
0358
0359 rtd->pop_wait = 0;
0360 mutex_unlock(&rtd->card->pcm_mutex);
0361
0362 cancel_delayed_work_sync(&rtd->delayed_work);
0363
0364 return 0;
0365
0366 err:
0367 mutex_unlock(&rtd->card->pcm_mutex);
0368 return ret;
0369 }
0370
0371 static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
0372 struct snd_compr_params *params)
0373 {
0374 struct snd_soc_pcm_runtime *fe = cstream->private_data;
0375 struct snd_pcm_substream *fe_substream =
0376 fe->pcm->streams[cstream->direction].substream;
0377 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
0378 int stream = cstream->direction;
0379 int ret;
0380
0381 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
0382
0383
0384
0385
0386
0387
0388 memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
0389 sizeof(struct snd_pcm_hw_params));
0390
0391 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
0392
0393 ret = dpcm_be_dai_hw_params(fe, stream);
0394 if (ret < 0)
0395 goto out;
0396
0397 ret = dpcm_be_dai_prepare(fe, stream);
0398 if (ret < 0)
0399 goto out;
0400
0401 ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
0402 if (ret < 0)
0403 goto out;
0404
0405 ret = snd_soc_component_compr_set_params(cstream, params);
0406 if (ret < 0)
0407 goto out;
0408
0409 ret = snd_soc_link_compr_set_params(cstream);
0410 if (ret < 0)
0411 goto out;
0412
0413 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
0414 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
0415
0416 out:
0417 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
0418 mutex_unlock(&fe->card->mutex);
0419 return ret;
0420 }
0421
0422 static int soc_compr_get_params(struct snd_compr_stream *cstream,
0423 struct snd_codec *params)
0424 {
0425 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0426 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0427 int ret = 0;
0428
0429 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
0430
0431 ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params);
0432 if (ret < 0)
0433 goto err;
0434
0435 ret = snd_soc_component_compr_get_params(cstream, params);
0436 err:
0437 mutex_unlock(&rtd->card->pcm_mutex);
0438 return ret;
0439 }
0440
0441 static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
0442 {
0443 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0444 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0445 int ret;
0446
0447 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
0448
0449 ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes);
0450 if (ret < 0)
0451 goto err;
0452
0453 ret = snd_soc_component_compr_ack(cstream, bytes);
0454 err:
0455 mutex_unlock(&rtd->card->pcm_mutex);
0456 return ret;
0457 }
0458
0459 static int soc_compr_pointer(struct snd_compr_stream *cstream,
0460 struct snd_compr_tstamp *tstamp)
0461 {
0462 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0463 int ret;
0464 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0465
0466 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
0467
0468 ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp);
0469 if (ret < 0)
0470 goto out;
0471
0472 ret = snd_soc_component_compr_pointer(cstream, tstamp);
0473 out:
0474 mutex_unlock(&rtd->card->pcm_mutex);
0475 return ret;
0476 }
0477
0478 static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
0479 struct snd_compr_metadata *metadata)
0480 {
0481 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0482 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0483 int ret;
0484
0485 ret = snd_soc_dai_compr_set_metadata(cpu_dai, cstream, metadata);
0486 if (ret < 0)
0487 return ret;
0488
0489 return snd_soc_component_compr_set_metadata(cstream, metadata);
0490 }
0491
0492 static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
0493 struct snd_compr_metadata *metadata)
0494 {
0495 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0496 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0497 int ret;
0498
0499 ret = snd_soc_dai_compr_get_metadata(cpu_dai, cstream, metadata);
0500 if (ret < 0)
0501 return ret;
0502
0503 return snd_soc_component_compr_get_metadata(cstream, metadata);
0504 }
0505
0506
0507 static struct snd_compr_ops soc_compr_ops = {
0508 .open = soc_compr_open,
0509 .free = soc_compr_free,
0510 .set_params = soc_compr_set_params,
0511 .set_metadata = soc_compr_set_metadata,
0512 .get_metadata = soc_compr_get_metadata,
0513 .get_params = soc_compr_get_params,
0514 .trigger = soc_compr_trigger,
0515 .pointer = soc_compr_pointer,
0516 .ack = soc_compr_ack,
0517 .get_caps = snd_soc_component_compr_get_caps,
0518 .get_codec_caps = snd_soc_component_compr_get_codec_caps,
0519 };
0520
0521
0522 static struct snd_compr_ops soc_compr_dyn_ops = {
0523 .open = soc_compr_open_fe,
0524 .free = soc_compr_free_fe,
0525 .set_params = soc_compr_set_params_fe,
0526 .get_params = soc_compr_get_params,
0527 .set_metadata = soc_compr_set_metadata,
0528 .get_metadata = soc_compr_get_metadata,
0529 .trigger = soc_compr_trigger_fe,
0530 .pointer = soc_compr_pointer,
0531 .ack = soc_compr_ack,
0532 .get_caps = snd_soc_component_compr_get_caps,
0533 .get_codec_caps = snd_soc_component_compr_get_codec_caps,
0534 };
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544 int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
0545 {
0546 struct snd_soc_component *component;
0547 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0548 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0549 struct snd_compr *compr;
0550 struct snd_pcm *be_pcm;
0551 char new_name[64];
0552 int ret = 0, direction = 0;
0553 int playback = 0, capture = 0;
0554 int i;
0555
0556
0557
0558
0559
0560 BUILD_BUG_ON((int)SNDRV_PCM_STREAM_PLAYBACK != (int)SND_COMPRESS_PLAYBACK);
0561 BUILD_BUG_ON((int)SNDRV_PCM_STREAM_CAPTURE != (int)SND_COMPRESS_CAPTURE);
0562
0563 if (rtd->num_cpus > 1 ||
0564 rtd->num_codecs > 1) {
0565 dev_err(rtd->card->dev,
0566 "Compress ASoC: Multi CPU/Codec not supported\n");
0567 return -EINVAL;
0568 }
0569
0570 if (!codec_dai) {
0571 dev_err(rtd->card->dev, "Missing codec\n");
0572 return -EINVAL;
0573 }
0574
0575
0576 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
0577 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
0578 playback = 1;
0579 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
0580 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
0581 capture = 1;
0582
0583
0584
0585
0586
0587 if (playback + capture != 1) {
0588 dev_err(rtd->card->dev,
0589 "Compress ASoC: Invalid direction for P %d, C %d\n",
0590 playback, capture);
0591 return -EINVAL;
0592 }
0593
0594 if (playback)
0595 direction = SND_COMPRESS_PLAYBACK;
0596 else
0597 direction = SND_COMPRESS_CAPTURE;
0598
0599 compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL);
0600 if (!compr)
0601 return -ENOMEM;
0602
0603 compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
0604 GFP_KERNEL);
0605 if (!compr->ops)
0606 return -ENOMEM;
0607
0608 if (rtd->dai_link->dynamic) {
0609 snprintf(new_name, sizeof(new_name), "(%s)",
0610 rtd->dai_link->stream_name);
0611
0612 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
0613 rtd->dai_link->dpcm_playback,
0614 rtd->dai_link->dpcm_capture, &be_pcm);
0615 if (ret < 0) {
0616 dev_err(rtd->card->dev,
0617 "Compress ASoC: can't create compressed for %s: %d\n",
0618 rtd->dai_link->name, ret);
0619 return ret;
0620 }
0621
0622 rtd->pcm = be_pcm;
0623 rtd->fe_compr = 1;
0624 if (rtd->dai_link->dpcm_playback)
0625 be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
0626 else if (rtd->dai_link->dpcm_capture)
0627 be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
0628 memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
0629 } else {
0630 snprintf(new_name, sizeof(new_name), "%s %s-%d",
0631 rtd->dai_link->stream_name, codec_dai->name, num);
0632
0633 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
0634 }
0635
0636 for_each_rtd_components(rtd, i, component) {
0637 if (!component->driver->compress_ops ||
0638 !component->driver->compress_ops->copy)
0639 continue;
0640
0641 compr->ops->copy = snd_soc_component_compr_copy;
0642 break;
0643 }
0644
0645 ret = snd_compress_new(rtd->card->snd_card, num, direction,
0646 new_name, compr);
0647 if (ret < 0) {
0648 component = asoc_rtd_to_codec(rtd, 0)->component;
0649 dev_err(component->dev,
0650 "Compress ASoC: can't create compress for codec %s: %d\n",
0651 component->name, ret);
0652 return ret;
0653 }
0654
0655
0656 rtd->close_delayed_work_func = snd_soc_close_delayed_work;
0657
0658 rtd->compr = compr;
0659 compr->private_data = rtd;
0660
0661 dev_dbg(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
0662 codec_dai->name, cpu_dai->name);
0663
0664 return 0;
0665 }
0666 EXPORT_SYMBOL_GPL(snd_soc_new_compress);