0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/debugfs.h>
0010 #include <linux/device.h>
0011 #include <sound/hda_register.h>
0012 #include <sound/hdaudio_ext.h>
0013 #include <sound/pcm_params.h>
0014 #include <sound/soc-acpi.h>
0015 #include <sound/soc-acpi-intel-match.h>
0016 #include <sound/soc-component.h>
0017 #include "avs.h"
0018 #include "path.h"
0019 #include "topology.h"
0020
0021 struct avs_dma_data {
0022 struct avs_tplg_path_template *template;
0023 struct avs_path *path;
0024
0025
0026
0027
0028
0029
0030 struct hdac_ext_stream *host_stream;
0031 };
0032
0033 static struct avs_tplg_path_template *
0034 avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
0035 {
0036 struct snd_soc_dapm_widget *dw;
0037 struct snd_soc_dapm_path *dp;
0038 enum snd_soc_dapm_direction dir;
0039
0040 if (direction == SNDRV_PCM_STREAM_CAPTURE) {
0041 dw = dai->capture_widget;
0042 dir = is_fe ? SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN;
0043 } else {
0044 dw = dai->playback_widget;
0045 dir = is_fe ? SND_SOC_DAPM_DIR_IN : SND_SOC_DAPM_DIR_OUT;
0046 }
0047
0048 dp = list_first_entry_or_null(&dw->edges[dir], typeof(*dp), list_node[dir]);
0049 if (!dp)
0050 return NULL;
0051
0052
0053 dw = (dp->source == dw) ? dp->sink : dp->source;
0054
0055 return dw->priv;
0056 }
0057
0058 static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe)
0059 {
0060 struct avs_tplg_path_template *template;
0061 struct avs_dma_data *data;
0062
0063 template = avs_dai_find_path_template(dai, is_fe, substream->stream);
0064 if (!template) {
0065 dev_err(dai->dev, "no %s path for dai %s, invalid tplg?\n",
0066 snd_pcm_stream_str(substream), dai->name);
0067 return -EINVAL;
0068 }
0069
0070 data = kzalloc(sizeof(*data), GFP_KERNEL);
0071 if (!data)
0072 return -ENOMEM;
0073
0074 data->template = template;
0075 snd_soc_dai_set_dma_data(dai, substream, data);
0076
0077 return 0;
0078 }
0079
0080 static int avs_dai_hw_params(struct snd_pcm_substream *substream,
0081 struct snd_pcm_hw_params *fe_hw_params,
0082 struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
0083 int dma_id)
0084 {
0085 struct avs_dma_data *data;
0086 struct avs_path *path;
0087 struct avs_dev *adev = to_avs_dev(dai->dev);
0088 int ret;
0089
0090 data = snd_soc_dai_get_dma_data(dai, substream);
0091
0092 dev_dbg(dai->dev, "%s FE hw_params str %p rtd %p",
0093 __func__, substream, substream->runtime);
0094 dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
0095 params_rate(fe_hw_params), params_channels(fe_hw_params),
0096 params_width(fe_hw_params), params_physical_width(fe_hw_params));
0097
0098 dev_dbg(dai->dev, "%s BE hw_params str %p rtd %p",
0099 __func__, substream, substream->runtime);
0100 dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
0101 params_rate(be_hw_params), params_channels(be_hw_params),
0102 params_width(be_hw_params), params_physical_width(be_hw_params));
0103
0104 path = avs_path_create(adev, dma_id, data->template, fe_hw_params, be_hw_params);
0105 if (IS_ERR(path)) {
0106 ret = PTR_ERR(path);
0107 dev_err(dai->dev, "create path failed: %d\n", ret);
0108 return ret;
0109 }
0110
0111 data->path = path;
0112 return 0;
0113 }
0114
0115 static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
0116 struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
0117 int dma_id)
0118 {
0119 struct snd_pcm_hw_params *fe_hw_params = NULL;
0120 struct snd_soc_pcm_runtime *fe, *be;
0121 struct snd_soc_dpcm *dpcm;
0122
0123 be = asoc_substream_to_rtd(substream);
0124 for_each_dpcm_fe(be, substream->stream, dpcm) {
0125 fe = dpcm->fe;
0126 fe_hw_params = &fe->dpcm[substream->stream].hw_params;
0127 }
0128
0129 return avs_dai_hw_params(substream, fe_hw_params, be_hw_params, dai, dma_id);
0130 }
0131
0132 static int avs_dai_prepare(struct avs_dev *adev, struct snd_pcm_substream *substream,
0133 struct snd_soc_dai *dai)
0134 {
0135 struct avs_dma_data *data;
0136 int ret;
0137
0138 data = snd_soc_dai_get_dma_data(dai, substream);
0139 if (!data->path)
0140 return 0;
0141
0142 ret = avs_path_reset(data->path);
0143 if (ret < 0) {
0144 dev_err(dai->dev, "reset path failed: %d\n", ret);
0145 return ret;
0146 }
0147
0148 ret = avs_path_pause(data->path);
0149 if (ret < 0)
0150 dev_err(dai->dev, "pause path failed: %d\n", ret);
0151 return ret;
0152 }
0153
0154 static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0155 {
0156 return avs_dai_startup(substream, dai, false);
0157 }
0158
0159 static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0160 {
0161 struct avs_dma_data *data;
0162
0163 data = snd_soc_dai_get_dma_data(dai, substream);
0164
0165 snd_soc_dai_set_dma_data(dai, substream, NULL);
0166 kfree(data);
0167 }
0168
0169 static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
0170 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
0171 {
0172 struct avs_dma_data *data;
0173
0174 data = snd_soc_dai_get_dma_data(dai, substream);
0175 if (data->path)
0176 return 0;
0177
0178
0179 return avs_dai_be_hw_params(substream, hw_params, dai, 0);
0180 }
0181
0182 static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0183 {
0184 struct avs_dma_data *data;
0185
0186 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
0187
0188 data = snd_soc_dai_get_dma_data(dai, substream);
0189 if (data->path) {
0190 avs_path_free(data->path);
0191 data->path = NULL;
0192 }
0193
0194 return 0;
0195 }
0196
0197 static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0198 {
0199 return avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
0200 }
0201
0202 static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
0203 struct snd_soc_dai *dai)
0204 {
0205 struct avs_dma_data *data;
0206 int ret = 0;
0207
0208 data = snd_soc_dai_get_dma_data(dai, substream);
0209
0210 switch (cmd) {
0211 case SNDRV_PCM_TRIGGER_START:
0212 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0213 ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
0214 if (ret < 0)
0215 dev_err(dai->dev, "run BE path failed: %d\n", ret);
0216 break;
0217
0218 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0219 case SNDRV_PCM_TRIGGER_STOP:
0220 ret = avs_path_pause(data->path);
0221 if (ret < 0)
0222 dev_err(dai->dev, "pause BE path failed: %d\n", ret);
0223
0224 if (cmd == SNDRV_PCM_TRIGGER_STOP) {
0225 ret = avs_path_reset(data->path);
0226 if (ret < 0)
0227 dev_err(dai->dev, "reset BE path failed: %d\n", ret);
0228 }
0229 break;
0230
0231 default:
0232 ret = -EINVAL;
0233 break;
0234 }
0235
0236 return ret;
0237 }
0238
0239 static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
0240 .startup = avs_dai_nonhda_be_startup,
0241 .shutdown = avs_dai_nonhda_be_shutdown,
0242 .hw_params = avs_dai_nonhda_be_hw_params,
0243 .hw_free = avs_dai_nonhda_be_hw_free,
0244 .prepare = avs_dai_nonhda_be_prepare,
0245 .trigger = avs_dai_nonhda_be_trigger,
0246 };
0247
0248 static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0249 {
0250 return avs_dai_startup(substream, dai, false);
0251 }
0252
0253 static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0254 {
0255 return avs_dai_nonhda_be_shutdown(substream, dai);
0256 }
0257
0258 static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
0259 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
0260 {
0261 struct avs_dma_data *data;
0262 struct hdac_ext_stream *link_stream;
0263
0264 data = snd_soc_dai_get_dma_data(dai, substream);
0265 if (data->path)
0266 return 0;
0267
0268 link_stream = substream->runtime->private_data;
0269
0270 return avs_dai_be_hw_params(substream, hw_params, dai,
0271 hdac_stream(link_stream)->stream_tag - 1);
0272 }
0273
0274 static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0275 {
0276 struct avs_dma_data *data;
0277 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
0278 struct hdac_ext_stream *link_stream;
0279 struct hdac_ext_link *link;
0280 struct hda_codec *codec;
0281
0282 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
0283
0284 data = snd_soc_dai_get_dma_data(dai, substream);
0285 if (!data->path)
0286 return 0;
0287
0288 link_stream = substream->runtime->private_data;
0289 link_stream->link_prepared = false;
0290 avs_path_free(data->path);
0291 data->path = NULL;
0292
0293
0294 codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
0295 link = snd_hdac_ext_bus_link_at(&codec->bus->core, codec->core.addr);
0296 if (!link)
0297 return -EINVAL;
0298
0299 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0300 snd_hdac_ext_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag);
0301
0302 return 0;
0303 }
0304
0305 static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0306 {
0307 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
0308 struct snd_pcm_runtime *runtime = substream->runtime;
0309 struct hdac_ext_stream *link_stream = runtime->private_data;
0310 struct hdac_ext_link *link;
0311 struct hda_codec *codec;
0312 struct hdac_bus *bus;
0313 unsigned int format_val;
0314 int ret;
0315
0316 if (link_stream->link_prepared)
0317 return 0;
0318
0319 codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
0320 bus = &codec->bus->core;
0321 format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
0322 runtime->sample_bits, 0);
0323
0324 snd_hdac_ext_stream_decouple(bus, link_stream, true);
0325 snd_hdac_ext_link_stream_reset(link_stream);
0326 snd_hdac_ext_link_stream_setup(link_stream, format_val);
0327
0328 link = snd_hdac_ext_bus_link_at(bus, codec->core.addr);
0329 if (!link)
0330 return -EINVAL;
0331
0332 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0333 snd_hdac_ext_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag);
0334
0335 ret = avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
0336 if (ret)
0337 return ret;
0338
0339 link_stream->link_prepared = true;
0340 return 0;
0341 }
0342
0343 static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
0344 struct snd_soc_dai *dai)
0345 {
0346 struct hdac_ext_stream *link_stream;
0347 struct avs_dma_data *data;
0348 int ret = 0;
0349
0350 dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd);
0351
0352 data = snd_soc_dai_get_dma_data(dai, substream);
0353 link_stream = substream->runtime->private_data;
0354
0355 switch (cmd) {
0356 case SNDRV_PCM_TRIGGER_START:
0357 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0358 snd_hdac_ext_link_stream_start(link_stream);
0359
0360 ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
0361 if (ret < 0)
0362 dev_err(dai->dev, "run BE path failed: %d\n", ret);
0363 break;
0364
0365 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0366 case SNDRV_PCM_TRIGGER_STOP:
0367 ret = avs_path_pause(data->path);
0368 if (ret < 0)
0369 dev_err(dai->dev, "pause BE path failed: %d\n", ret);
0370
0371 snd_hdac_ext_link_stream_clear(link_stream);
0372
0373 if (cmd == SNDRV_PCM_TRIGGER_STOP) {
0374 ret = avs_path_reset(data->path);
0375 if (ret < 0)
0376 dev_err(dai->dev, "reset BE path failed: %d\n", ret);
0377 }
0378 break;
0379
0380 default:
0381 ret = -EINVAL;
0382 break;
0383 }
0384
0385 return ret;
0386 }
0387
0388 static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
0389 .startup = avs_dai_hda_be_startup,
0390 .shutdown = avs_dai_hda_be_shutdown,
0391 .hw_params = avs_dai_hda_be_hw_params,
0392 .hw_free = avs_dai_hda_be_hw_free,
0393 .prepare = avs_dai_hda_be_prepare,
0394 .trigger = avs_dai_hda_be_trigger,
0395 };
0396
0397 static const unsigned int rates[] = {
0398 8000, 11025, 12000, 16000,
0399 22050, 24000, 32000, 44100,
0400 48000, 64000, 88200, 96000,
0401 128000, 176400, 192000,
0402 };
0403
0404 static const struct snd_pcm_hw_constraint_list hw_rates = {
0405 .count = ARRAY_SIZE(rates),
0406 .list = rates,
0407 .mask = 0,
0408 };
0409
0410 static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0411 {
0412 struct snd_pcm_runtime *runtime = substream->runtime;
0413 struct avs_dma_data *data;
0414 struct avs_dev *adev = to_avs_dev(dai->dev);
0415 struct hdac_bus *bus = &adev->base.core;
0416 struct hdac_ext_stream *host_stream;
0417 int ret;
0418
0419 ret = avs_dai_startup(substream, dai, true);
0420 if (ret)
0421 return ret;
0422
0423 data = snd_soc_dai_get_dma_data(dai, substream);
0424
0425 host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST);
0426 if (!host_stream) {
0427 kfree(data);
0428 return -EBUSY;
0429 }
0430
0431 data->host_stream = host_stream;
0432 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
0433
0434 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
0435 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_rates);
0436 snd_pcm_set_sync(substream);
0437
0438 dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p",
0439 __func__, hdac_stream(host_stream)->stream_tag, substream);
0440
0441 return 0;
0442 }
0443
0444 static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0445 {
0446 struct avs_dma_data *data;
0447
0448 data = snd_soc_dai_get_dma_data(dai, substream);
0449
0450 snd_soc_dai_set_dma_data(dai, substream, NULL);
0451 snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
0452 kfree(data);
0453 }
0454
0455 static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
0456 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
0457 {
0458 struct snd_pcm_hw_params *be_hw_params = NULL;
0459 struct snd_soc_pcm_runtime *fe, *be;
0460 struct snd_soc_dpcm *dpcm;
0461 struct avs_dma_data *data;
0462 struct hdac_ext_stream *host_stream;
0463 int ret;
0464
0465 data = snd_soc_dai_get_dma_data(dai, substream);
0466 if (data->path)
0467 return 0;
0468
0469 host_stream = data->host_stream;
0470
0471 hdac_stream(host_stream)->bufsize = 0;
0472 hdac_stream(host_stream)->period_bytes = 0;
0473 hdac_stream(host_stream)->format_val = 0;
0474
0475 fe = asoc_substream_to_rtd(substream);
0476 for_each_dpcm_be(fe, substream->stream, dpcm) {
0477 be = dpcm->be;
0478 be_hw_params = &be->dpcm[substream->stream].hw_params;
0479 }
0480
0481 ret = avs_dai_hw_params(substream, hw_params, be_hw_params, dai,
0482 hdac_stream(host_stream)->stream_tag - 1);
0483 if (ret)
0484 goto create_err;
0485
0486 ret = avs_path_bind(data->path);
0487 if (ret < 0) {
0488 dev_err(dai->dev, "bind FE <-> BE failed: %d\n", ret);
0489 goto bind_err;
0490 }
0491
0492 return 0;
0493
0494 bind_err:
0495 avs_path_free(data->path);
0496 data->path = NULL;
0497 create_err:
0498 snd_pcm_lib_free_pages(substream);
0499 return ret;
0500 }
0501
0502 static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0503 {
0504 struct avs_dma_data *data;
0505 struct hdac_ext_stream *host_stream;
0506 int ret;
0507
0508 dev_dbg(dai->dev, "%s fe HW_FREE str %p rtd %p",
0509 __func__, substream, substream->runtime);
0510
0511 data = snd_soc_dai_get_dma_data(dai, substream);
0512 if (!data->path)
0513 return 0;
0514
0515 host_stream = data->host_stream;
0516
0517 ret = avs_path_unbind(data->path);
0518 if (ret < 0)
0519 dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
0520
0521 avs_path_free(data->path);
0522 data->path = NULL;
0523 snd_hdac_stream_cleanup(hdac_stream(host_stream));
0524 hdac_stream(host_stream)->prepared = false;
0525
0526 ret = snd_pcm_lib_free_pages(substream);
0527 if (ret < 0)
0528 dev_dbg(dai->dev, "Failed to free pages!\n");
0529
0530 return ret;
0531 }
0532
0533 static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
0534 {
0535 struct snd_pcm_runtime *runtime = substream->runtime;
0536 struct avs_dma_data *data;
0537 struct avs_dev *adev = to_avs_dev(dai->dev);
0538 struct hdac_ext_stream *host_stream;
0539 struct hdac_bus *bus;
0540 unsigned int format_val;
0541 int ret;
0542
0543 data = snd_soc_dai_get_dma_data(dai, substream);
0544 host_stream = data->host_stream;
0545
0546 if (hdac_stream(host_stream)->prepared)
0547 return 0;
0548
0549 bus = hdac_stream(host_stream)->bus;
0550 snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
0551 snd_hdac_stream_reset(hdac_stream(host_stream));
0552
0553 format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
0554 runtime->sample_bits, 0);
0555
0556 ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
0557 if (ret < 0)
0558 return ret;
0559
0560 ret = snd_hdac_stream_setup(hdac_stream(host_stream));
0561 if (ret < 0)
0562 return ret;
0563
0564 ret = avs_dai_prepare(adev, substream, dai);
0565 if (ret)
0566 return ret;
0567
0568 hdac_stream(host_stream)->prepared = true;
0569 return 0;
0570 }
0571
0572 static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
0573 {
0574 struct avs_dma_data *data;
0575 struct hdac_ext_stream *host_stream;
0576 struct hdac_bus *bus;
0577 unsigned long flags;
0578 int ret = 0;
0579
0580 data = snd_soc_dai_get_dma_data(dai, substream);
0581 host_stream = data->host_stream;
0582 bus = hdac_stream(host_stream)->bus;
0583
0584 switch (cmd) {
0585 case SNDRV_PCM_TRIGGER_START:
0586 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0587 spin_lock_irqsave(&bus->reg_lock, flags);
0588 snd_hdac_stream_start(hdac_stream(host_stream), true);
0589 spin_unlock_irqrestore(&bus->reg_lock, flags);
0590
0591 ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
0592 if (ret < 0)
0593 dev_err(dai->dev, "run FE path failed: %d\n", ret);
0594 break;
0595
0596 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0597 case SNDRV_PCM_TRIGGER_STOP:
0598 ret = avs_path_pause(data->path);
0599 if (ret < 0)
0600 dev_err(dai->dev, "pause FE path failed: %d\n", ret);
0601
0602 spin_lock_irqsave(&bus->reg_lock, flags);
0603 snd_hdac_stream_stop(hdac_stream(host_stream));
0604 spin_unlock_irqrestore(&bus->reg_lock, flags);
0605
0606 if (cmd == SNDRV_PCM_TRIGGER_STOP) {
0607 ret = avs_path_reset(data->path);
0608 if (ret < 0)
0609 dev_err(dai->dev, "reset FE path failed: %d\n", ret);
0610 }
0611 break;
0612
0613 default:
0614 ret = -EINVAL;
0615 break;
0616 }
0617
0618 return ret;
0619 }
0620
0621 const struct snd_soc_dai_ops avs_dai_fe_ops = {
0622 .startup = avs_dai_fe_startup,
0623 .shutdown = avs_dai_fe_shutdown,
0624 .hw_params = avs_dai_fe_hw_params,
0625 .hw_free = avs_dai_fe_hw_free,
0626 .prepare = avs_dai_fe_prepare,
0627 .trigger = avs_dai_fe_trigger,
0628 };
0629
0630 static ssize_t topology_name_read(struct file *file, char __user *user_buf, size_t count,
0631 loff_t *ppos)
0632 {
0633 struct snd_soc_component *component = file->private_data;
0634 struct snd_soc_card *card = component->card;
0635 struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
0636 char buf[64];
0637 size_t len;
0638
0639 len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
0640 mach->tplg_filename);
0641
0642 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0643 }
0644
0645 static const struct file_operations topology_name_fops = {
0646 .open = simple_open,
0647 .read = topology_name_read,
0648 .llseek = default_llseek,
0649 };
0650
0651 static int avs_component_load_libraries(struct avs_soc_component *acomp)
0652 {
0653 struct avs_tplg *tplg = acomp->tplg;
0654 struct avs_dev *adev = to_avs_dev(acomp->base.dev);
0655 int ret;
0656
0657 if (!tplg->num_libs)
0658 return 0;
0659
0660
0661 ret = pm_runtime_resume_and_get(adev->dev);
0662 if (ret < 0)
0663 return ret;
0664
0665 avs_hda_clock_gating_enable(adev, false);
0666 avs_hda_l1sen_enable(adev, false);
0667
0668 ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
0669
0670 avs_hda_l1sen_enable(adev, true);
0671 avs_hda_clock_gating_enable(adev, true);
0672
0673 if (!ret)
0674 ret = avs_module_info_init(adev, false);
0675
0676 pm_runtime_mark_last_busy(adev->dev);
0677 pm_runtime_put_autosuspend(adev->dev);
0678
0679 return ret;
0680 }
0681
0682 static int avs_component_probe(struct snd_soc_component *component)
0683 {
0684 struct snd_soc_card *card = component->card;
0685 struct snd_soc_acpi_mach *mach;
0686 struct avs_soc_component *acomp;
0687 struct avs_dev *adev;
0688 char *filename;
0689 int ret;
0690
0691 dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
0692 mach = dev_get_platdata(card->dev);
0693 acomp = to_avs_soc_component(component);
0694 adev = to_avs_dev(component->dev);
0695
0696 acomp->tplg = avs_tplg_new(component);
0697 if (!acomp->tplg)
0698 return -ENOMEM;
0699
0700 if (!mach->tplg_filename)
0701 goto finalize;
0702
0703
0704 filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
0705 mach->tplg_filename);
0706 if (!filename)
0707 return -ENOMEM;
0708
0709 ret = avs_load_topology(component, filename);
0710 kfree(filename);
0711 if (ret < 0)
0712 return ret;
0713
0714 ret = avs_component_load_libraries(acomp);
0715 if (ret < 0) {
0716 dev_err(card->dev, "libraries loading failed: %d\n", ret);
0717 goto err_load_libs;
0718 }
0719
0720 finalize:
0721 debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
0722 &topology_name_fops);
0723
0724 mutex_lock(&adev->comp_list_mutex);
0725 list_add_tail(&acomp->node, &adev->comp_list);
0726 mutex_unlock(&adev->comp_list_mutex);
0727
0728 return 0;
0729
0730 err_load_libs:
0731 avs_remove_topology(component);
0732 return ret;
0733 }
0734
0735 static void avs_component_remove(struct snd_soc_component *component)
0736 {
0737 struct avs_soc_component *acomp = to_avs_soc_component(component);
0738 struct snd_soc_acpi_mach *mach;
0739 struct avs_dev *adev = to_avs_dev(component->dev);
0740 int ret;
0741
0742 mach = dev_get_platdata(component->card->dev);
0743
0744 mutex_lock(&adev->comp_list_mutex);
0745 list_del(&acomp->node);
0746 mutex_unlock(&adev->comp_list_mutex);
0747
0748 if (mach->tplg_filename) {
0749 ret = avs_remove_topology(component);
0750 if (ret < 0)
0751 dev_err(component->dev, "unload topology failed: %d\n", ret);
0752 }
0753 }
0754
0755 static int avs_component_open(struct snd_soc_component *component,
0756 struct snd_pcm_substream *substream)
0757 {
0758 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
0759 struct snd_pcm_hardware hwparams;
0760
0761
0762 if (rtd->dai_link->no_pcm)
0763 return 0;
0764
0765 hwparams.info = SNDRV_PCM_INFO_MMAP |
0766 SNDRV_PCM_INFO_MMAP_VALID |
0767 SNDRV_PCM_INFO_INTERLEAVED |
0768 SNDRV_PCM_INFO_PAUSE |
0769 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP;
0770
0771 hwparams.formats = SNDRV_PCM_FMTBIT_S16_LE |
0772 SNDRV_PCM_FMTBIT_S24_LE |
0773 SNDRV_PCM_FMTBIT_S32_LE;
0774 hwparams.period_bytes_min = 128;
0775 hwparams.period_bytes_max = AZX_MAX_BUF_SIZE / 2;
0776 hwparams.periods_min = 2;
0777 hwparams.periods_max = AZX_MAX_FRAG;
0778 hwparams.buffer_bytes_max = AZX_MAX_BUF_SIZE;
0779 hwparams.fifo_size = 0;
0780
0781 return snd_soc_set_runtime_hwparams(substream, &hwparams);
0782 }
0783
0784 static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
0785 {
0786 return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
0787 (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
0788 }
0789
0790 static snd_pcm_uframes_t
0791 avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
0792 {
0793 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
0794 struct avs_dma_data *data;
0795 struct hdac_ext_stream *host_stream;
0796 unsigned int pos;
0797
0798 data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
0799 if (!data->host_stream)
0800 return 0;
0801
0802 host_stream = data->host_stream;
0803 pos = avs_hda_stream_dpib_read(host_stream);
0804
0805 if (pos >= hdac_stream(host_stream)->bufsize)
0806 pos = 0;
0807
0808 return bytes_to_frames(substream->runtime, pos);
0809 }
0810
0811 static int avs_component_mmap(struct snd_soc_component *component,
0812 struct snd_pcm_substream *substream,
0813 struct vm_area_struct *vma)
0814 {
0815 return snd_pcm_lib_default_mmap(substream, vma);
0816 }
0817
0818 #define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
0819
0820 static int avs_component_construct(struct snd_soc_component *component,
0821 struct snd_soc_pcm_runtime *rtd)
0822 {
0823 struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
0824 struct snd_pcm *pcm = rtd->pcm;
0825
0826 if (dai->driver->playback.channels_min)
0827 snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
0828 SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
0829 MAX_PREALLOC_SIZE);
0830
0831 if (dai->driver->capture.channels_min)
0832 snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
0833 SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
0834 MAX_PREALLOC_SIZE);
0835
0836 return 0;
0837 }
0838
0839 static const struct snd_soc_component_driver avs_component_driver = {
0840 .name = "avs-pcm",
0841 .probe = avs_component_probe,
0842 .remove = avs_component_remove,
0843 .open = avs_component_open,
0844 .pointer = avs_component_pointer,
0845 .mmap = avs_component_mmap,
0846 .pcm_construct = avs_component_construct,
0847 .module_get_upon_open = 1,
0848 .topology_name_prefix = "intel/avs",
0849 };
0850
0851 static int avs_soc_component_register(struct device *dev, const char *name,
0852 const struct snd_soc_component_driver *drv,
0853 struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
0854 {
0855 struct avs_soc_component *acomp;
0856 int ret;
0857
0858 acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
0859 if (!acomp)
0860 return -ENOMEM;
0861
0862 ret = snd_soc_component_initialize(&acomp->base, drv, dev);
0863 if (ret < 0)
0864 return ret;
0865
0866
0867 acomp->base.name = name;
0868 INIT_LIST_HEAD(&acomp->node);
0869
0870 return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
0871 }
0872
0873 static struct snd_soc_dai_driver dmic_cpu_dais[] = {
0874 {
0875 .name = "DMIC Pin",
0876 .ops = &avs_dai_nonhda_be_ops,
0877 .capture = {
0878 .stream_name = "DMIC Rx",
0879 .channels_min = 1,
0880 .channels_max = 4,
0881 .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
0882 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
0883 },
0884 },
0885 {
0886 .name = "DMIC WoV Pin",
0887 .ops = &avs_dai_nonhda_be_ops,
0888 .capture = {
0889 .stream_name = "DMIC WoV Rx",
0890 .channels_min = 1,
0891 .channels_max = 4,
0892 .rates = SNDRV_PCM_RATE_16000,
0893 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0894 },
0895 },
0896 };
0897
0898 int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
0899 {
0900 return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
0901 ARRAY_SIZE(dmic_cpu_dais));
0902 }
0903
0904 static const struct snd_soc_dai_driver i2s_dai_template = {
0905 .ops = &avs_dai_nonhda_be_ops,
0906 .playback = {
0907 .channels_min = 1,
0908 .channels_max = 8,
0909 .rates = SNDRV_PCM_RATE_8000_192000 |
0910 SNDRV_PCM_RATE_KNOT,
0911 .formats = SNDRV_PCM_FMTBIT_S16_LE |
0912 SNDRV_PCM_FMTBIT_S24_LE |
0913 SNDRV_PCM_FMTBIT_S32_LE,
0914 },
0915 .capture = {
0916 .channels_min = 1,
0917 .channels_max = 8,
0918 .rates = SNDRV_PCM_RATE_8000_192000 |
0919 SNDRV_PCM_RATE_KNOT,
0920 .formats = SNDRV_PCM_FMTBIT_S16_LE |
0921 SNDRV_PCM_FMTBIT_S24_LE |
0922 SNDRV_PCM_FMTBIT_S32_LE,
0923 },
0924 };
0925
0926 int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
0927 unsigned long *tdms)
0928 {
0929 struct snd_soc_dai_driver *cpus, *dai;
0930 size_t ssp_count, cpu_count;
0931 int i, j;
0932
0933 ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
0934 cpu_count = hweight_long(port_mask);
0935 if (tdms)
0936 for_each_set_bit(i, &port_mask, ssp_count)
0937 cpu_count += hweight_long(tdms[i]);
0938
0939 cpus = devm_kzalloc(adev->dev, sizeof(*cpus) * cpu_count, GFP_KERNEL);
0940 if (!cpus)
0941 return -ENOMEM;
0942
0943 dai = cpus;
0944 for_each_set_bit(i, &port_mask, ssp_count) {
0945 memcpy(dai, &i2s_dai_template, sizeof(*dai));
0946
0947 dai->name =
0948 devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
0949 dai->playback.stream_name =
0950 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
0951 dai->capture.stream_name =
0952 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
0953
0954 if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
0955 return -ENOMEM;
0956 dai++;
0957 }
0958
0959 if (!tdms)
0960 goto plat_register;
0961
0962 for_each_set_bit(i, &port_mask, ssp_count) {
0963 for_each_set_bit(j, &tdms[i], ssp_count) {
0964 memcpy(dai, &i2s_dai_template, sizeof(*dai));
0965
0966 dai->name =
0967 devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
0968 dai->playback.stream_name =
0969 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
0970 dai->capture.stream_name =
0971 devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
0972
0973 if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
0974 return -ENOMEM;
0975 dai++;
0976 }
0977 }
0978
0979 plat_register:
0980 return avs_soc_component_register(adev->dev, name, &avs_component_driver, cpus, cpu_count);
0981 }
0982
0983
0984 static const struct snd_soc_dai_driver hda_cpu_dai = {
0985 .ops = &avs_dai_hda_be_ops,
0986 .playback = {
0987 .channels_min = 1,
0988 .channels_max = 8,
0989 .rates = SNDRV_PCM_RATE_8000_192000,
0990 .formats = SNDRV_PCM_FMTBIT_S16_LE |
0991 SNDRV_PCM_FMTBIT_S24_LE |
0992 SNDRV_PCM_FMTBIT_S32_LE,
0993 },
0994 .capture = {
0995 .channels_min = 1,
0996 .channels_max = 8,
0997 .rates = SNDRV_PCM_RATE_8000_192000,
0998 .formats = SNDRV_PCM_FMTBIT_S16_LE |
0999 SNDRV_PCM_FMTBIT_S24_LE |
1000 SNDRV_PCM_FMTBIT_S32_LE,
1001 },
1002 };
1003
1004 static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1005 {
1006 struct snd_soc_acpi_mach *mach;
1007 struct snd_soc_dai *dai, *save;
1008 struct hda_codec *codec;
1009 char name[32];
1010
1011 mach = dev_get_platdata(component->card->dev);
1012 codec = mach->pdata;
1013 sprintf(name, "%s-cpu", dev_name(&codec->core.dev));
1014
1015 for_each_component_dais_safe(component, dai, save) {
1016 if (!strstr(dai->driver->name, name))
1017 continue;
1018
1019 if (dai->playback_widget)
1020 snd_soc_dapm_free_widget(dai->playback_widget);
1021 if (dai->capture_widget)
1022 snd_soc_dapm_free_widget(dai->capture_widget);
1023 snd_soc_unregister_dai(dai);
1024 }
1025 }
1026
1027 static int avs_component_hda_probe(struct snd_soc_component *component)
1028 {
1029 struct snd_soc_dapm_context *dapm;
1030 struct snd_soc_dai_driver *dais;
1031 struct snd_soc_acpi_mach *mach;
1032 struct hda_codec *codec;
1033 struct hda_pcm *pcm;
1034 const char *cname;
1035 int pcm_count = 0, ret, i;
1036
1037 mach = dev_get_platdata(component->card->dev);
1038 if (!mach)
1039 return -EINVAL;
1040
1041 codec = mach->pdata;
1042 if (list_empty(&codec->pcm_list_head))
1043 return -EINVAL;
1044 list_for_each_entry(pcm, &codec->pcm_list_head, list)
1045 pcm_count++;
1046
1047 dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1048 GFP_KERNEL);
1049 if (!dais)
1050 return -ENOMEM;
1051
1052 cname = dev_name(&codec->core.dev);
1053 dapm = snd_soc_component_get_dapm(component);
1054 pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1055
1056 for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1057 struct snd_soc_dai *dai;
1058
1059 memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1060 dais[i].id = i;
1061 dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1062 "%s-cpu%d", cname, i);
1063 if (!dais[i].name) {
1064 ret = -ENOMEM;
1065 goto exit;
1066 }
1067
1068 if (pcm->stream[0].substreams) {
1069 dais[i].playback.stream_name =
1070 devm_kasprintf(component->dev, GFP_KERNEL,
1071 "%s-cpu%d Tx", cname, i);
1072 if (!dais[i].playback.stream_name) {
1073 ret = -ENOMEM;
1074 goto exit;
1075 }
1076 }
1077
1078 if (pcm->stream[1].substreams) {
1079 dais[i].capture.stream_name =
1080 devm_kasprintf(component->dev, GFP_KERNEL,
1081 "%s-cpu%d Rx", cname, i);
1082 if (!dais[i].capture.stream_name) {
1083 ret = -ENOMEM;
1084 goto exit;
1085 }
1086 }
1087
1088 dai = snd_soc_register_dai(component, &dais[i], false);
1089 if (!dai) {
1090 dev_err(component->dev, "register dai for %s failed\n",
1091 pcm->name);
1092 ret = -EINVAL;
1093 goto exit;
1094 }
1095
1096 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1097 if (ret < 0) {
1098 dev_err(component->dev, "create widgets failed: %d\n",
1099 ret);
1100 goto exit;
1101 }
1102 }
1103
1104 ret = avs_component_probe(component);
1105 exit:
1106 if (ret)
1107 avs_component_hda_unregister_dais(component);
1108
1109 return ret;
1110 }
1111
1112 static void avs_component_hda_remove(struct snd_soc_component *component)
1113 {
1114 avs_component_hda_unregister_dais(component);
1115 avs_component_remove(component);
1116 }
1117
1118 static int avs_component_hda_open(struct snd_soc_component *component,
1119 struct snd_pcm_substream *substream)
1120 {
1121 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1122 struct hdac_ext_stream *link_stream;
1123 struct hda_codec *codec;
1124
1125
1126 if (!rtd->dai_link->no_pcm)
1127 return avs_component_open(component, substream);
1128
1129 codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
1130 link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
1131 HDAC_EXT_STREAM_TYPE_LINK);
1132 if (!link_stream)
1133 return -EBUSY;
1134
1135 substream->runtime->private_data = link_stream;
1136 return 0;
1137 }
1138
1139 static int avs_component_hda_close(struct snd_soc_component *component,
1140 struct snd_pcm_substream *substream)
1141 {
1142 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
1143 struct hdac_ext_stream *link_stream;
1144
1145
1146 if (!rtd->dai_link->no_pcm)
1147 return 0;
1148
1149 link_stream = substream->runtime->private_data;
1150 snd_hdac_ext_stream_release(link_stream, HDAC_EXT_STREAM_TYPE_LINK);
1151 substream->runtime->private_data = NULL;
1152
1153 return 0;
1154 }
1155
1156 static const struct snd_soc_component_driver avs_hda_component_driver = {
1157 .name = "avs-hda-pcm",
1158 .probe = avs_component_hda_probe,
1159 .remove = avs_component_hda_remove,
1160 .open = avs_component_hda_open,
1161 .close = avs_component_hda_close,
1162 .pointer = avs_component_pointer,
1163 .mmap = avs_component_mmap,
1164 .pcm_construct = avs_component_construct,
1165
1166
1167
1168
1169
1170 .probe_order = SND_SOC_COMP_ORDER_LATE,
1171 .remove_order = SND_SOC_COMP_ORDER_EARLY,
1172 .module_get_upon_open = 1,
1173 .topology_name_prefix = "intel/avs",
1174 };
1175
1176 int avs_hda_platform_register(struct avs_dev *adev, const char *name)
1177 {
1178 return avs_soc_component_register(adev->dev, name,
1179 &avs_hda_component_driver, NULL, 0);
1180 }