Linux Audio

Check our new training course

Loading...
v6.13.7
   1// SPDX-License-Identifier: GPL-2.0-only
   2//
   3// Copyright(c) 2021-2022 Intel Corporation
   4//
   5// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
   6//          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
   7//
   8
   9#include <linux/debugfs.h>
  10#include <linux/device.h>
  11#include <sound/hda_register.h>
  12#include <sound/hdaudio_ext.h>
  13#include <sound/pcm_params.h>
  14#include <sound/soc-acpi.h>
  15#include <sound/soc-acpi-intel-match.h>
  16#include <sound/soc-component.h>
  17#include "avs.h"
  18#include "path.h"
  19#include "pcm.h"
  20#include "topology.h"
  21#include "../../codecs/hda.h"
  22
  23struct avs_dma_data {
  24	struct avs_tplg_path_template *template;
  25	struct avs_path *path;
  26	struct avs_dev *adev;
  27
  28	/* LINK-stream utilized in BE operations while HOST in FE ones. */
  29	union {
  30		struct hdac_ext_stream *link_stream;
  31		struct hdac_ext_stream *host_stream;
  32	};
  33
  34	struct work_struct period_elapsed_work;
  35	struct snd_pcm_substream *substream;
  36};
  37
  38static struct avs_tplg_path_template *
  39avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
  40{
  41	struct snd_soc_dapm_widget *dw = snd_soc_dai_get_widget(dai, direction);
  42	struct snd_soc_dapm_path *dp;
  43	enum snd_soc_dapm_direction dir;
  44
  45	if (direction == SNDRV_PCM_STREAM_CAPTURE) {
  46		dir = is_fe ? SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN;
  47	} else {
  48		dir = is_fe ? SND_SOC_DAPM_DIR_IN : SND_SOC_DAPM_DIR_OUT;
  49	}
  50
  51	dp = list_first_entry_or_null(&dw->edges[dir], typeof(*dp), list_node[dir]);
  52	if (!dp)
  53		return NULL;
  54
  55	/* Get the other widget, with actual path template data */
  56	dw = (dp->source == dw) ? dp->sink : dp->source;
  57
  58	return dw->priv;
  59}
  60
  61static void avs_period_elapsed_work(struct work_struct *work)
  62{
  63	struct avs_dma_data *data = container_of(work, struct avs_dma_data, period_elapsed_work);
  64
  65	snd_pcm_period_elapsed(data->substream);
  66}
  67
  68void avs_period_elapsed(struct snd_pcm_substream *substream)
  69{
  70	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  71	struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
  72	struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
  73
  74	schedule_work(&data->period_elapsed_work);
  75}
  76
  77static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
  78{
  79	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  80	struct avs_dev *adev = to_avs_dev(dai->component->dev);
  81	struct avs_tplg_path_template *template;
  82	struct avs_dma_data *data;
  83
  84	template = avs_dai_find_path_template(dai, !rtd->dai_link->no_pcm, substream->stream);
  85	if (!template) {
  86		dev_err(dai->dev, "no %s path for dai %s, invalid tplg?\n",
  87			snd_pcm_stream_str(substream), dai->name);
  88		return -EINVAL;
  89	}
  90
  91	data = kzalloc(sizeof(*data), GFP_KERNEL);
  92	if (!data)
  93		return -ENOMEM;
  94
  95	data->substream = substream;
  96	data->template = template;
  97	data->adev = adev;
  98	INIT_WORK(&data->period_elapsed_work, avs_period_elapsed_work);
  99	snd_soc_dai_set_dma_data(dai, substream, data);
 100
 101	if (rtd->dai_link->ignore_suspend)
 102		adev->num_lp_paths++;
 103
 104	return 0;
 105}
 106
 107static void avs_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 108{
 109	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 110	struct avs_dma_data *data;
 111
 112	data = snd_soc_dai_get_dma_data(dai, substream);
 113
 114	if (rtd->dai_link->ignore_suspend)
 115		data->adev->num_lp_paths--;
 116
 117	snd_soc_dai_set_dma_data(dai, substream, NULL);
 118	kfree(data);
 119}
 120
 121static int avs_dai_hw_params(struct snd_pcm_substream *substream,
 122			     struct snd_pcm_hw_params *fe_hw_params,
 123			     struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
 124			     int dma_id)
 125{
 126	struct avs_dma_data *data;
 127	struct avs_path *path;
 
 128	int ret;
 129
 130	data = snd_soc_dai_get_dma_data(dai, substream);
 131
 132	dev_dbg(dai->dev, "%s FE hw_params str %p rtd %p",
 133		__func__, substream, substream->runtime);
 134	dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
 135		params_rate(fe_hw_params), params_channels(fe_hw_params),
 136		params_width(fe_hw_params), params_physical_width(fe_hw_params));
 137
 138	dev_dbg(dai->dev, "%s BE hw_params str %p rtd %p",
 139		__func__, substream, substream->runtime);
 140	dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
 141		params_rate(be_hw_params), params_channels(be_hw_params),
 142		params_width(be_hw_params), params_physical_width(be_hw_params));
 143
 144	path = avs_path_create(data->adev, dma_id, data->template, fe_hw_params, be_hw_params);
 145	if (IS_ERR(path)) {
 146		ret = PTR_ERR(path);
 147		dev_err(dai->dev, "create path failed: %d\n", ret);
 148		return ret;
 149	}
 150
 151	data->path = path;
 152	return 0;
 153}
 154
 155static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
 156				struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
 157				int dma_id)
 158{
 159	struct snd_pcm_hw_params *fe_hw_params = NULL;
 160	struct snd_soc_pcm_runtime *fe, *be;
 161	struct snd_soc_dpcm *dpcm;
 162
 163	be = snd_soc_substream_to_rtd(substream);
 164	for_each_dpcm_fe(be, substream->stream, dpcm) {
 165		fe = dpcm->fe;
 166		fe_hw_params = &fe->dpcm[substream->stream].hw_params;
 167	}
 168
 169	return avs_dai_hw_params(substream, fe_hw_params, be_hw_params, dai, dma_id);
 170}
 171
 172static int avs_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 
 173{
 174	struct avs_dma_data *data;
 175	int ret;
 176
 177	data = snd_soc_dai_get_dma_data(dai, substream);
 178	if (!data->path)
 179		return 0;
 180
 181	ret = avs_path_reset(data->path);
 182	if (ret < 0) {
 183		dev_err(dai->dev, "reset path failed: %d\n", ret);
 184		return ret;
 185	}
 186
 187	ret = avs_path_pause(data->path);
 188	if (ret < 0)
 189		dev_err(dai->dev, "pause path failed: %d\n", ret);
 190	return ret;
 191}
 192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 193static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
 194				       struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
 195{
 196	struct avs_dma_data *data;
 197
 198	data = snd_soc_dai_get_dma_data(dai, substream);
 199	if (data->path)
 200		return 0;
 201
 202	/* Actual port-id comes from topology. */
 203	return avs_dai_be_hw_params(substream, hw_params, dai, 0);
 204}
 205
 206static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 207{
 208	struct avs_dma_data *data;
 209
 210	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
 211
 212	data = snd_soc_dai_get_dma_data(dai, substream);
 213	if (data->path) {
 214		avs_path_free(data->path);
 215		data->path = NULL;
 216	}
 217
 218	return 0;
 219}
 220
 
 
 
 
 
 221static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 222				     struct snd_soc_dai *dai)
 223{
 224	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 225	struct avs_dma_data *data;
 226	int ret = 0;
 227
 228	data = snd_soc_dai_get_dma_data(dai, substream);
 229
 230	switch (cmd) {
 231	case SNDRV_PCM_TRIGGER_RESUME:
 232		if (rtd->dai_link->ignore_suspend)
 233			break;
 234		fallthrough;
 235	case SNDRV_PCM_TRIGGER_START:
 236	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 237		ret = avs_path_pause(data->path);
 238		if (ret < 0) {
 239			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 240			break;
 241		}
 242
 243		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 244		if (ret < 0)
 245			dev_err(dai->dev, "run BE path failed: %d\n", ret);
 246		break;
 247
 248	case SNDRV_PCM_TRIGGER_SUSPEND:
 249		if (rtd->dai_link->ignore_suspend)
 250			break;
 251		fallthrough;
 252	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 253	case SNDRV_PCM_TRIGGER_STOP:
 254		ret = avs_path_pause(data->path);
 255		if (ret < 0)
 256			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 257
 258		ret = avs_path_reset(data->path);
 259		if (ret < 0)
 260			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
 261		break;
 262
 263	default:
 264		ret = -EINVAL;
 265		break;
 266	}
 267
 268	return ret;
 269}
 270
 271static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
 272	.startup = avs_dai_startup,
 273	.shutdown = avs_dai_shutdown,
 274	.hw_params = avs_dai_nonhda_be_hw_params,
 275	.hw_free = avs_dai_nonhda_be_hw_free,
 276	.prepare = avs_dai_prepare,
 277	.trigger = avs_dai_nonhda_be_trigger,
 278};
 279
 
 
 280static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 281{
 282	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 283	struct hdac_ext_stream *link_stream;
 284	struct avs_dma_data *data;
 285	struct hda_codec *codec;
 286	int ret;
 287
 288	ret = avs_dai_startup(substream, dai);
 289	if (ret)
 290		return ret;
 291
 292	codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
 293	link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
 294						 HDAC_EXT_STREAM_TYPE_LINK);
 295	if (!link_stream) {
 296		avs_dai_shutdown(substream, dai);
 297		return -EBUSY;
 298	}
 299
 300	data = snd_soc_dai_get_dma_data(dai, substream);
 301	data->link_stream = link_stream;
 302	substream->runtime->private_data = link_stream;
 303	return 0;
 304}
 305
 306static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 307{
 308	struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
 309
 310	snd_hdac_ext_stream_release(data->link_stream, HDAC_EXT_STREAM_TYPE_LINK);
 311	substream->runtime->private_data = NULL;
 312	avs_dai_shutdown(substream, dai);
 313}
 314
 315static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
 316				    struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
 317{
 318	struct avs_dma_data *data;
 
 319
 320	data = snd_soc_dai_get_dma_data(dai, substream);
 321	if (data->path)
 322		return 0;
 323
 
 
 324	return avs_dai_be_hw_params(substream, hw_params, dai,
 325				    hdac_stream(data->link_stream)->stream_tag - 1);
 326}
 327
 328static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 329{
 330	struct avs_dma_data *data;
 331	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 332	struct hdac_ext_stream *link_stream;
 333	struct hdac_ext_link *link;
 334	struct hda_codec *codec;
 335
 336	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
 337
 338	data = snd_soc_dai_get_dma_data(dai, substream);
 339	if (!data->path)
 340		return 0;
 341
 342	link_stream = data->link_stream;
 343	link_stream->link_prepared = false;
 344	avs_path_free(data->path);
 345	data->path = NULL;
 346
 347	/* clear link <-> stream mapping */
 348	codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
 349	link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
 350	if (!link)
 351		return -EINVAL;
 352
 353	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 354		snd_hdac_ext_bus_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag);
 355
 356	return 0;
 357}
 358
 359static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 360{
 361	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 362	struct snd_pcm_runtime *runtime = substream->runtime;
 363	const struct snd_soc_pcm_stream *stream_info;
 364	struct hdac_ext_stream *link_stream;
 365	struct hdac_ext_link *link;
 366	struct avs_dma_data *data;
 367	struct hda_codec *codec;
 368	struct hdac_bus *bus;
 369	unsigned int format_val;
 370	unsigned int bits;
 371	int ret;
 372
 373	data = snd_soc_dai_get_dma_data(dai, substream);
 374	link_stream = data->link_stream;
 375
 376	if (link_stream->link_prepared)
 377		return 0;
 378
 379	codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
 380	bus = &codec->bus->core;
 381	stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
 382	bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
 383					   stream_info->sig_bits);
 384	format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
 385
 386	snd_hdac_ext_stream_decouple(bus, link_stream, true);
 387	snd_hdac_ext_stream_reset(link_stream);
 388	snd_hdac_ext_stream_setup(link_stream, format_val);
 389
 390	link = snd_hdac_ext_bus_get_hlink_by_addr(bus, codec->core.addr);
 391	if (!link)
 392		return -EINVAL;
 393
 394	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 395		snd_hdac_ext_bus_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag);
 396
 397	ret = avs_dai_prepare(substream, dai);
 398	if (ret)
 399		return ret;
 400
 401	link_stream->link_prepared = true;
 402	return 0;
 403}
 404
 405static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 406				  struct snd_soc_dai *dai)
 407{
 408	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 
 409	struct avs_dma_data *data;
 410	int ret = 0;
 411
 412	dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd);
 413
 414	data = snd_soc_dai_get_dma_data(dai, substream);
 
 415
 416	switch (cmd) {
 417	case SNDRV_PCM_TRIGGER_RESUME:
 418		if (rtd->dai_link->ignore_suspend)
 419			break;
 420		fallthrough;
 421	case SNDRV_PCM_TRIGGER_START:
 422	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 423		snd_hdac_ext_stream_start(data->link_stream);
 424
 425		ret = avs_path_pause(data->path);
 426		if (ret < 0) {
 427			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 428			break;
 429		}
 430
 431		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 432		if (ret < 0)
 433			dev_err(dai->dev, "run BE path failed: %d\n", ret);
 434		break;
 435
 436	case SNDRV_PCM_TRIGGER_SUSPEND:
 437		if (rtd->dai_link->ignore_suspend)
 438			break;
 439		fallthrough;
 440	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 441	case SNDRV_PCM_TRIGGER_STOP:
 442		ret = avs_path_pause(data->path);
 443		if (ret < 0)
 444			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 445
 446		snd_hdac_ext_stream_clear(data->link_stream);
 447
 448		ret = avs_path_reset(data->path);
 449		if (ret < 0)
 450			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
 451		break;
 452
 453	default:
 454		ret = -EINVAL;
 455		break;
 456	}
 457
 458	return ret;
 459}
 460
 461static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
 462	.startup = avs_dai_hda_be_startup,
 463	.shutdown = avs_dai_hda_be_shutdown,
 464	.hw_params = avs_dai_hda_be_hw_params,
 465	.hw_free = avs_dai_hda_be_hw_free,
 466	.prepare = avs_dai_hda_be_prepare,
 467	.trigger = avs_dai_hda_be_trigger,
 468};
 469
 470static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
 471{
 472	struct snd_interval *interval = hw_param_interval(params, rule->var);
 473	struct snd_interval to;
 474
 475	snd_interval_any(&to);
 476	to.integer = interval->integer;
 477	to.max = interval->max;
 478	/*
 479	 * Commonly 2ms buffer size is used in HDA scenarios whereas 4ms is used
 480	 * when streaming through GPDMA. Align to the latter to account for both.
 481	 */
 482	to.min = params_rate(params) / 1000 * 4;
 483
 484	if (rule->var == SNDRV_PCM_HW_PARAM_PERIOD_SIZE)
 485		to.min /= params_periods(params);
 486
 487	return snd_interval_refine(interval, &to);
 488}
 489
 490static int avs_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
 491{
 492	struct snd_pcm_runtime *runtime = substream->runtime;
 493	int ret;
 494
 495	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 496	if (ret < 0)
 497		return ret;
 498
 499	/* Avoid wrap-around with wall-clock. */
 500	ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
 501	if (ret < 0)
 502		return ret;
 
 503
 504	/* Adjust buffer and period size based on the audio format. */
 505	snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, hw_rule_param_size, NULL,
 506			    SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_CHANNELS,
 507			    SNDRV_PCM_HW_PARAM_RATE, -1);
 508	snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, hw_rule_param_size, NULL,
 509			    SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_CHANNELS,
 510			    SNDRV_PCM_HW_PARAM_RATE, -1);
 511
 512	return 0;
 513}
 514
 515static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 516{
 517	struct hdac_ext_stream *host_stream;
 518	struct avs_dma_data *data;
 519	struct hdac_bus *bus;
 
 
 520	int ret;
 521
 522	ret = avs_pcm_hw_constraints_init(substream);
 523	if (ret)
 524		return ret;
 525
 526	ret = avs_dai_startup(substream, dai);
 527	if (ret)
 528		return ret;
 529
 530	data = snd_soc_dai_get_dma_data(dai, substream);
 531	bus = &data->adev->base.core;
 532
 533	host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST);
 534	if (!host_stream) {
 535		avs_dai_shutdown(substream, dai);
 536		return -EBUSY;
 537	}
 538
 539	data->host_stream = host_stream;
 
 
 
 
 
 
 
 
 
 
 
 
 
 540	snd_pcm_set_sync(substream);
 541
 542	dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p",
 543		__func__, hdac_stream(host_stream)->stream_tag, substream);
 544
 545	return 0;
 
 
 
 
 546}
 547
 548static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 549{
 
 
 550	struct avs_dma_data *data;
 551
 
 
 
 552	data = snd_soc_dai_get_dma_data(dai, substream);
 553
 
 554	snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
 555	avs_dai_shutdown(substream, dai);
 556}
 557
 558static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
 559				struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
 560{
 561	struct snd_pcm_hw_params *be_hw_params = NULL;
 562	struct snd_soc_pcm_runtime *fe, *be;
 563	struct snd_soc_dpcm *dpcm;
 564	struct avs_dma_data *data;
 565	struct hdac_ext_stream *host_stream;
 566	int ret;
 567
 568	data = snd_soc_dai_get_dma_data(dai, substream);
 569	if (data->path)
 570		return 0;
 571
 572	host_stream = data->host_stream;
 573
 574	hdac_stream(host_stream)->bufsize = 0;
 575	hdac_stream(host_stream)->period_bytes = 0;
 576	hdac_stream(host_stream)->format_val = 0;
 577
 578	fe = snd_soc_substream_to_rtd(substream);
 579	for_each_dpcm_be(fe, substream->stream, dpcm) {
 580		be = dpcm->be;
 581		be_hw_params = &be->dpcm[substream->stream].hw_params;
 582	}
 583
 584	ret = avs_dai_hw_params(substream, hw_params, be_hw_params, dai,
 585				hdac_stream(host_stream)->stream_tag - 1);
 586	if (ret)
 587		goto create_err;
 588
 589	ret = avs_path_bind(data->path);
 590	if (ret < 0) {
 591		dev_err(dai->dev, "bind FE <-> BE failed: %d\n", ret);
 592		goto bind_err;
 593	}
 594
 595	return 0;
 596
 597bind_err:
 598	avs_path_free(data->path);
 599	data->path = NULL;
 600create_err:
 601	snd_pcm_lib_free_pages(substream);
 602	return ret;
 603}
 604
 605static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 606{
 607	struct avs_dma_data *data;
 608	struct hdac_ext_stream *host_stream;
 609	int ret;
 610
 611	dev_dbg(dai->dev, "%s fe HW_FREE str %p rtd %p",
 612		__func__, substream, substream->runtime);
 613
 614	data = snd_soc_dai_get_dma_data(dai, substream);
 615	if (!data->path)
 616		return 0;
 617
 618	host_stream = data->host_stream;
 619
 620	ret = avs_path_unbind(data->path);
 621	if (ret < 0)
 622		dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
 623
 624	avs_path_free(data->path);
 625	data->path = NULL;
 626	snd_hdac_stream_cleanup(hdac_stream(host_stream));
 627	hdac_stream(host_stream)->prepared = false;
 628
 629	return ret;
 630}
 631
 632static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 633{
 634	int ret;
 635
 636	ret = __avs_dai_fe_hw_free(substream, dai);
 637	snd_pcm_lib_free_pages(substream);
 638
 639	return ret;
 640}
 641
 642static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 643{
 644	struct snd_pcm_runtime *runtime = substream->runtime;
 645	const struct snd_soc_pcm_stream *stream_info;
 646	struct avs_dma_data *data;
 
 647	struct hdac_ext_stream *host_stream;
 648	unsigned int format_val;
 649	struct hdac_bus *bus;
 650	unsigned int bits;
 651	int ret;
 652
 653	data = snd_soc_dai_get_dma_data(dai, substream);
 654	host_stream = data->host_stream;
 655
 656	if (hdac_stream(host_stream)->prepared)
 657		return 0;
 658
 659	bus = hdac_stream(host_stream)->bus;
 660	snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
 661	snd_hdac_stream_reset(hdac_stream(host_stream));
 662
 663	stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
 664	bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
 665					   stream_info->sig_bits);
 666	format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
 667
 668	ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
 669	if (ret < 0)
 670		return ret;
 671
 672	ret = snd_hdac_ext_host_stream_setup(host_stream, false);
 673	if (ret < 0)
 674		return ret;
 675
 676	ret = avs_dai_prepare(substream, dai);
 677	if (ret)
 678		return ret;
 679
 680	hdac_stream(host_stream)->prepared = true;
 681	return 0;
 682}
 683
 684static void avs_hda_stream_start(struct hdac_bus *bus, struct hdac_ext_stream *host_stream)
 685{
 686	struct hdac_stream *first_running = NULL;
 687	struct hdac_stream *pos;
 688	struct avs_dev *adev = hdac_to_avs(bus);
 689
 690	list_for_each_entry(pos, &bus->stream_list, list) {
 691		if (pos->running) {
 692			if (first_running)
 693				break; /* more than one running */
 694			first_running = pos;
 695		}
 696	}
 697
 698	/*
 699	 * If host_stream is a CAPTURE stream and will be the only one running,
 700	 * disable L1SEN to avoid sound clipping.
 701	 */
 702	if (!first_running) {
 703		if (hdac_stream(host_stream)->direction == SNDRV_PCM_STREAM_CAPTURE)
 704			avs_hda_l1sen_enable(adev, false);
 705		snd_hdac_stream_start(hdac_stream(host_stream));
 706		return;
 707	}
 708
 709	snd_hdac_stream_start(hdac_stream(host_stream));
 710	/*
 711	 * If host_stream is the first stream to break the rule above,
 712	 * re-enable L1SEN.
 713	 */
 714	if (list_entry_is_head(pos, &bus->stream_list, list) &&
 715	    first_running->direction == SNDRV_PCM_STREAM_CAPTURE)
 716		avs_hda_l1sen_enable(adev, true);
 717}
 718
 719static void avs_hda_stream_stop(struct hdac_bus *bus, struct hdac_ext_stream *host_stream)
 720{
 721	struct hdac_stream *first_running = NULL;
 722	struct hdac_stream *pos;
 723	struct avs_dev *adev = hdac_to_avs(bus);
 724
 725	list_for_each_entry(pos, &bus->stream_list, list) {
 726		if (pos == hdac_stream(host_stream))
 727			continue; /* ignore stream that is about to be stopped */
 728		if (pos->running) {
 729			if (first_running)
 730				break; /* more than one running */
 731			first_running = pos;
 732		}
 733	}
 734
 735	/*
 736	 * If host_stream is a CAPTURE stream and is the only one running,
 737	 * re-enable L1SEN.
 738	 */
 739	if (!first_running) {
 740		snd_hdac_stream_stop(hdac_stream(host_stream));
 741		if (hdac_stream(host_stream)->direction == SNDRV_PCM_STREAM_CAPTURE)
 742			avs_hda_l1sen_enable(adev, true);
 743		return;
 744	}
 745
 746	/*
 747	 * If by stopping host_stream there is only a single, CAPTURE stream running
 748	 * left, disable L1SEN to avoid sound clipping.
 749	 */
 750	if (list_entry_is_head(pos, &bus->stream_list, list) &&
 751	    first_running->direction == SNDRV_PCM_STREAM_CAPTURE)
 752		avs_hda_l1sen_enable(adev, false);
 753
 754	snd_hdac_stream_stop(hdac_stream(host_stream));
 755}
 756
 757static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
 758{
 759	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 760	struct avs_dma_data *data;
 761	struct hdac_ext_stream *host_stream;
 762	struct hdac_bus *bus;
 763	unsigned long flags;
 764	int ret = 0;
 765
 766	data = snd_soc_dai_get_dma_data(dai, substream);
 767	host_stream = data->host_stream;
 768	bus = hdac_stream(host_stream)->bus;
 769
 770	switch (cmd) {
 771	case SNDRV_PCM_TRIGGER_RESUME:
 772		if (rtd->dai_link->ignore_suspend)
 773			break;
 774		fallthrough;
 775	case SNDRV_PCM_TRIGGER_START:
 776	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 777		spin_lock_irqsave(&bus->reg_lock, flags);
 778		avs_hda_stream_start(bus, host_stream);
 779		spin_unlock_irqrestore(&bus->reg_lock, flags);
 780
 781		/* Timeout on DRSM poll shall not stop the resume so ignore the result. */
 782		if (cmd == SNDRV_PCM_TRIGGER_RESUME)
 783			snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
 784
 785		ret = avs_path_pause(data->path);
 786		if (ret < 0) {
 787			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
 788			break;
 789		}
 790
 791		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 792		if (ret < 0)
 793			dev_err(dai->dev, "run FE path failed: %d\n", ret);
 794
 795		break;
 796
 797	case SNDRV_PCM_TRIGGER_SUSPEND:
 798		if (rtd->dai_link->ignore_suspend)
 799			break;
 800		fallthrough;
 801	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 802	case SNDRV_PCM_TRIGGER_STOP:
 803		ret = avs_path_pause(data->path);
 804		if (ret < 0)
 805			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
 806
 807		spin_lock_irqsave(&bus->reg_lock, flags);
 808		avs_hda_stream_stop(bus, host_stream);
 809		spin_unlock_irqrestore(&bus->reg_lock, flags);
 810
 811		ret = avs_path_reset(data->path);
 812		if (ret < 0)
 813			dev_err(dai->dev, "reset FE path failed: %d\n", ret);
 814		break;
 815
 816	default:
 817		ret = -EINVAL;
 818		break;
 819	}
 820
 821	return ret;
 822}
 823
 824const struct snd_soc_dai_ops avs_dai_fe_ops = {
 825	.startup = avs_dai_fe_startup,
 826	.shutdown = avs_dai_fe_shutdown,
 827	.hw_params = avs_dai_fe_hw_params,
 828	.hw_free = avs_dai_fe_hw_free,
 829	.prepare = avs_dai_fe_prepare,
 830	.trigger = avs_dai_fe_trigger,
 831};
 832
 833static ssize_t topology_name_read(struct file *file, char __user *user_buf, size_t count,
 834				  loff_t *ppos)
 835{
 836	struct snd_soc_component *component = file->private_data;
 837	struct snd_soc_card *card = component->card;
 838	struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
 839	char buf[64];
 840	size_t len;
 841
 842	len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
 843			mach->tplg_filename);
 844
 845	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 846}
 847
 848static const struct file_operations topology_name_fops = {
 849	.open = simple_open,
 850	.read = topology_name_read,
 851	.llseek = default_llseek,
 852};
 853
 854static int avs_component_load_libraries(struct avs_soc_component *acomp)
 855{
 856	struct avs_tplg *tplg = acomp->tplg;
 857	struct avs_dev *adev = to_avs_dev(acomp->base.dev);
 858	int ret;
 859
 860	if (!tplg->num_libs)
 861		return 0;
 862
 863	/* Parent device may be asleep and library loading involves IPCs. */
 864	ret = pm_runtime_resume_and_get(adev->dev);
 865	if (ret < 0)
 866		return ret;
 867
 868	avs_hda_power_gating_enable(adev, false);
 869	avs_hda_clock_gating_enable(adev, false);
 870	avs_hda_l1sen_enable(adev, false);
 871
 872	ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
 873
 874	avs_hda_l1sen_enable(adev, true);
 875	avs_hda_clock_gating_enable(adev, true);
 876	avs_hda_power_gating_enable(adev, true);
 877
 878	if (!ret)
 879		ret = avs_module_info_init(adev, false);
 880
 881	pm_runtime_mark_last_busy(adev->dev);
 882	pm_runtime_put_autosuspend(adev->dev);
 883
 884	return ret;
 885}
 886
 887static int avs_component_probe(struct snd_soc_component *component)
 888{
 889	struct snd_soc_card *card = component->card;
 890	struct snd_soc_acpi_mach *mach;
 891	struct avs_soc_component *acomp;
 892	struct avs_dev *adev;
 893	char *filename;
 894	int ret;
 895
 896	dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
 897	mach = dev_get_platdata(card->dev);
 898	acomp = to_avs_soc_component(component);
 899	adev = to_avs_dev(component->dev);
 900
 901	acomp->tplg = avs_tplg_new(component);
 902	if (!acomp->tplg)
 903		return -ENOMEM;
 904
 905	if (!mach->tplg_filename)
 906		goto finalize;
 907
 908	/* Load specified topology and create debugfs for it. */
 909	filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
 910			     mach->tplg_filename);
 911	if (!filename)
 912		return -ENOMEM;
 913
 914	ret = avs_load_topology(component, filename);
 915	kfree(filename);
 916	if (ret == -ENOENT && !strncmp(mach->tplg_filename, "hda-", 4)) {
 917		unsigned int vendor_id;
 918
 919		if (sscanf(mach->tplg_filename, "hda-%08x-tplg.bin", &vendor_id) != 1)
 920			return ret;
 921
 922		if (((vendor_id >> 16) & 0xFFFF) == 0x8086)
 923			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
 924							     "hda-8086-generic-tplg.bin");
 925		else
 926			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
 927							     "hda-generic-tplg.bin");
 928
 929		filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
 930				     mach->tplg_filename);
 931		if (!filename)
 932			return -ENOMEM;
 933
 934		dev_info(card->dev, "trying to load fallback topology %s\n", mach->tplg_filename);
 935		ret = avs_load_topology(component, filename);
 936		kfree(filename);
 937	}
 938	if (ret < 0)
 939		return ret;
 940
 941	ret = avs_component_load_libraries(acomp);
 942	if (ret < 0) {
 943		dev_err(card->dev, "libraries loading failed: %d\n", ret);
 944		goto err_load_libs;
 945	}
 946
 947finalize:
 948	debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
 949			    &topology_name_fops);
 950
 951	mutex_lock(&adev->comp_list_mutex);
 952	list_add_tail(&acomp->node, &adev->comp_list);
 953	mutex_unlock(&adev->comp_list_mutex);
 954
 955	return 0;
 956
 957err_load_libs:
 958	avs_remove_topology(component);
 959	return ret;
 960}
 961
 962static void avs_component_remove(struct snd_soc_component *component)
 963{
 964	struct avs_soc_component *acomp = to_avs_soc_component(component);
 965	struct snd_soc_acpi_mach *mach;
 966	struct avs_dev *adev = to_avs_dev(component->dev);
 967	int ret;
 968
 969	mach = dev_get_platdata(component->card->dev);
 970
 971	mutex_lock(&adev->comp_list_mutex);
 972	list_del(&acomp->node);
 973	mutex_unlock(&adev->comp_list_mutex);
 974
 975	if (mach->tplg_filename) {
 976		ret = avs_remove_topology(component);
 977		if (ret < 0)
 978			dev_err(component->dev, "unload topology failed: %d\n", ret);
 979	}
 980}
 981
 982static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data)
 983{
 984	struct snd_pcm_substream *substream;
 985	struct snd_soc_pcm_runtime *rtd;
 986	int ret;
 987
 988	substream = data->substream;
 989	rtd = snd_soc_substream_to_rtd(substream);
 990
 991	ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai);
 992	if (ret)
 993		dev_err(dai->dev, "hw_params on resume failed: %d\n", ret);
 994
 995	return ret;
 996}
 997
 998static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
 999{
1000	struct hdac_ext_stream *host_stream;
1001	struct hdac_stream *hstream;
1002	struct hdac_bus *bus;
1003	int ret;
1004
1005	host_stream = data->host_stream;
1006	hstream = hdac_stream(host_stream);
1007	bus = hdac_stream(host_stream)->bus;
1008
1009	/* Set DRSM before programming stream and position registers. */
1010	snd_hdac_stream_drsm_enable(bus, true, hstream->index);
1011
1012	ret = dai->driver->ops->prepare(data->substream, dai);
1013	if (ret) {
1014		dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret);
1015		return ret;
1016	}
1017
1018	writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1019	writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1020	writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1021	writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1022
1023	/* As per HW spec recommendation, program LPIB and DPIB to the same value. */
1024	snd_hdac_stream_set_lpib(hstream, hstream->lpib);
1025	snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
1026
1027	return 0;
1028}
1029
1030static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
1031{
1032	int ret;
1033
1034	ret = dai->driver->ops->prepare(data->substream, dai);
1035	if (ret)
1036		dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret);
1037
1038	return ret;
1039}
1040
1041static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1042{
1043	struct hdac_ext_stream *host_stream;
1044	int ret;
1045
1046	host_stream = data->host_stream;
1047
1048	/* Store position addresses so we can resume from them later on. */
1049	hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream));
1050	host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1051	host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1052	host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1053	host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1054
1055	ret = __avs_dai_fe_hw_free(data->substream, dai);
1056	if (ret < 0)
1057		dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret);
1058
1059	return ret;
1060}
1061
1062static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1063{
1064	int ret;
1065
1066	ret = dai->driver->ops->hw_free(data->substream, dai);
1067	if (ret < 0)
1068		dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret);
1069
1070	return ret;
1071}
1072
1073static int avs_component_pm_op(struct snd_soc_component *component, bool be,
1074			       int (*op)(struct snd_soc_dai *, struct avs_dma_data *))
1075{
1076	struct snd_soc_pcm_runtime *rtd;
1077	struct avs_dma_data *data;
1078	struct snd_soc_dai *dai;
1079	int ret;
1080
1081	for_each_component_dais(component, dai) {
1082		data = snd_soc_dai_dma_data_get_playback(dai);
1083		if (data) {
1084			rtd = snd_soc_substream_to_rtd(data->substream);
1085			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1086				ret = op(dai, data);
1087				if (ret < 0) {
1088					__snd_pcm_set_state(data->substream->runtime,
1089							    SNDRV_PCM_STATE_DISCONNECTED);
1090					return ret;
1091				}
1092			}
1093		}
1094
1095		data = snd_soc_dai_dma_data_get_capture(dai);
1096		if (data) {
1097			rtd = snd_soc_substream_to_rtd(data->substream);
1098			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1099				ret = op(dai, data);
1100				if (ret < 0) {
1101					__snd_pcm_set_state(data->substream->runtime,
1102							    SNDRV_PCM_STATE_DISCONNECTED);
1103					return ret;
1104				}
1105			}
1106		}
1107	}
1108
1109	return 0;
1110}
1111
1112static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be)
1113{
1114	return avs_component_pm_op(component, be, &avs_dai_resume_hw_params);
1115}
1116
1117static int avs_component_resume_prepare(struct snd_soc_component *component, bool be)
1118{
1119	int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1120
1121	if (be)
1122		prepare_cb = &avs_dai_resume_be_prepare;
1123	else
1124		prepare_cb = &avs_dai_resume_fe_prepare;
1125
1126	return avs_component_pm_op(component, be, prepare_cb);
1127}
1128
1129static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be)
1130{
1131	int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1132
1133	if (be)
1134		hw_free_cb = &avs_dai_suspend_be_hw_free;
1135	else
1136		hw_free_cb = &avs_dai_suspend_fe_hw_free;
1137
1138	return avs_component_pm_op(component, be, hw_free_cb);
1139}
1140
1141static int avs_component_suspend(struct snd_soc_component *component)
1142{
1143	int ret;
1144
1145	/*
1146	 * When freeing paths, FEs need to be first as they perform
1147	 * path unbinding.
1148	 */
1149	ret = avs_component_suspend_hw_free(component, false);
1150	if (ret)
1151		return ret;
1152
1153	return avs_component_suspend_hw_free(component, true);
1154}
1155
1156static int avs_component_resume(struct snd_soc_component *component)
1157{
1158	int ret;
1159
1160	/*
1161	 * When creating paths, FEs need to be last as they perform
1162	 * path binding.
1163	 */
1164	ret = avs_component_resume_hw_params(component, true);
1165	if (ret)
1166		return ret;
1167
1168	ret = avs_component_resume_hw_params(component, false);
1169	if (ret)
1170		return ret;
1171
1172	/* It is expected that the LINK stream is prepared first. */
1173	ret = avs_component_resume_prepare(component, true);
1174	if (ret)
1175		return ret;
1176
1177	return avs_component_resume_prepare(component, false);
1178}
1179
1180static const struct snd_pcm_hardware avs_pcm_hardware = {
1181	.info			= SNDRV_PCM_INFO_MMAP |
1182				  SNDRV_PCM_INFO_MMAP_VALID |
1183				  SNDRV_PCM_INFO_INTERLEAVED |
1184				  SNDRV_PCM_INFO_PAUSE |
1185				  SNDRV_PCM_INFO_RESUME |
1186				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
1187	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
1188				  SNDRV_PCM_FMTBIT_S32_LE,
1189	.subformats		= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1190				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1191				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1192	.buffer_bytes_max	= AZX_MAX_BUF_SIZE,
1193	.period_bytes_min	= 128,
1194	.period_bytes_max	= AZX_MAX_BUF_SIZE / 2,
1195	.periods_min		= 2,
1196	.periods_max		= AZX_MAX_FRAG,
1197	.fifo_size		= 0,
1198};
1199
1200static int avs_component_open(struct snd_soc_component *component,
1201			      struct snd_pcm_substream *substream)
1202{
1203	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1204
1205	/* only FE DAI links are handled here */
1206	if (rtd->dai_link->no_pcm)
1207		return 0;
1208
1209	return snd_soc_set_runtime_hwparams(substream, &avs_pcm_hardware);
1210}
1211
1212static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
1213{
1214	return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1215		     (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
1216}
1217
1218static snd_pcm_uframes_t
1219avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
1220{
1221	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1222	struct avs_dma_data *data;
1223	struct hdac_ext_stream *host_stream;
1224	unsigned int pos;
1225
1226	data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0), substream);
1227	if (!data->host_stream)
1228		return 0;
1229
1230	host_stream = data->host_stream;
1231	pos = avs_hda_stream_dpib_read(host_stream);
1232
1233	if (pos >= hdac_stream(host_stream)->bufsize)
1234		pos = 0;
1235
1236	return bytes_to_frames(substream->runtime, pos);
1237}
1238
1239static int avs_component_mmap(struct snd_soc_component *component,
1240			      struct snd_pcm_substream *substream,
1241			      struct vm_area_struct *vma)
1242{
1243	return snd_pcm_lib_default_mmap(substream, vma);
1244}
1245
1246#define MAX_PREALLOC_SIZE	(32 * 1024 * 1024)
1247
1248static int avs_component_construct(struct snd_soc_component *component,
1249				   struct snd_soc_pcm_runtime *rtd)
1250{
1251	struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
1252	struct snd_pcm *pcm = rtd->pcm;
1253
1254	if (dai->driver->playback.channels_min)
1255		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
1256					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1257					   MAX_PREALLOC_SIZE);
1258
1259	if (dai->driver->capture.channels_min)
1260		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
1261					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1262					   MAX_PREALLOC_SIZE);
1263
1264	return 0;
1265}
1266
1267static const struct snd_soc_component_driver avs_component_driver = {
1268	.name			= "avs-pcm",
1269	.probe			= avs_component_probe,
1270	.remove			= avs_component_remove,
1271	.suspend		= avs_component_suspend,
1272	.resume			= avs_component_resume,
1273	.open			= avs_component_open,
1274	.pointer		= avs_component_pointer,
1275	.mmap			= avs_component_mmap,
1276	.pcm_construct		= avs_component_construct,
1277	.module_get_upon_open	= 1, /* increment refcount when a pcm is opened */
1278	.topology_name_prefix	= "intel/avs",
1279};
1280
1281int avs_soc_component_register(struct device *dev, const char *name,
1282			       const struct snd_soc_component_driver *drv,
1283			       struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
1284{
1285	struct avs_soc_component *acomp;
1286	int ret;
1287
1288	acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
1289	if (!acomp)
1290		return -ENOMEM;
1291
1292	ret = snd_soc_component_initialize(&acomp->base, drv, dev);
1293	if (ret < 0)
1294		return ret;
1295
1296	/* force name change after ASoC is done with its init */
1297	acomp->base.name = name;
1298	INIT_LIST_HEAD(&acomp->node);
1299
1300	return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
1301}
1302
1303static struct snd_soc_dai_driver dmic_cpu_dais[] = {
1304{
1305	.name = "DMIC Pin",
1306	.ops = &avs_dai_nonhda_be_ops,
1307	.capture = {
1308		.stream_name	= "DMIC Rx",
1309		.channels_min	= 1,
1310		.channels_max	= 4,
1311		.rates		= SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
1312		.formats	= SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
1313	},
1314},
1315{
1316	.name = "DMIC WoV Pin",
1317	.ops = &avs_dai_nonhda_be_ops,
1318	.capture = {
1319		.stream_name	= "DMIC WoV Rx",
1320		.channels_min	= 1,
1321		.channels_max	= 4,
1322		.rates		= SNDRV_PCM_RATE_16000,
1323		.formats	= SNDRV_PCM_FMTBIT_S16_LE,
1324	},
1325},
1326};
1327
1328int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
1329{
1330	return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
1331					  ARRAY_SIZE(dmic_cpu_dais));
1332}
1333
1334static const struct snd_soc_dai_driver i2s_dai_template = {
1335	.ops = &avs_dai_nonhda_be_ops,
1336	.playback = {
1337		.channels_min	= 1,
1338		.channels_max	= 8,
1339		.rates		= SNDRV_PCM_RATE_8000_192000 |
1340				  SNDRV_PCM_RATE_12000 |
1341				  SNDRV_PCM_RATE_24000 |
1342				  SNDRV_PCM_RATE_128000,
1343		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1344				  SNDRV_PCM_FMTBIT_S32_LE,
1345		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1346				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1347				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1348	},
1349	.capture = {
1350		.channels_min	= 1,
1351		.channels_max	= 8,
1352		.rates		= SNDRV_PCM_RATE_8000_192000 |
1353				  SNDRV_PCM_RATE_12000 |
1354				  SNDRV_PCM_RATE_24000 |
1355				  SNDRV_PCM_RATE_128000,
1356		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1357				  SNDRV_PCM_FMTBIT_S32_LE,
1358		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1359				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1360				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1361	},
1362};
1363
1364int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
1365			      unsigned long *tdms)
1366{
1367	struct snd_soc_dai_driver *cpus, *dai;
1368	size_t ssp_count, cpu_count;
1369	int i, j;
1370
1371	ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
1372
1373	cpu_count = 0;
1374	for_each_set_bit(i, &port_mask, ssp_count)
1375		if (!tdms || test_bit(0, &tdms[i]))
1376			cpu_count++;
1377	if (tdms)
1378		for_each_set_bit(i, &port_mask, ssp_count)
1379			cpu_count += hweight_long(tdms[i]);
1380
1381	cpus = devm_kzalloc(adev->dev, sizeof(*cpus) * cpu_count, GFP_KERNEL);
1382	if (!cpus)
1383		return -ENOMEM;
1384
1385	dai = cpus;
1386	for_each_set_bit(i, &port_mask, ssp_count) {
1387		if (!tdms || test_bit(0, &tdms[i])) {
1388			memcpy(dai, &i2s_dai_template, sizeof(*dai));
1389
1390			dai->name =
1391				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
1392			dai->playback.stream_name =
1393				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
1394			dai->capture.stream_name =
1395				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
1396
1397			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1398				return -ENOMEM;
1399			dai++;
1400		}
1401	}
1402
1403	if (!tdms)
1404		goto plat_register;
1405
1406	for_each_set_bit(i, &port_mask, ssp_count) {
1407		for_each_set_bit(j, &tdms[i], ssp_count) {
1408			memcpy(dai, &i2s_dai_template, sizeof(*dai));
1409
1410			dai->name =
1411				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
1412			dai->playback.stream_name =
1413				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
1414			dai->capture.stream_name =
1415				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
1416
1417			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1418				return -ENOMEM;
1419			dai++;
1420		}
1421	}
1422
1423plat_register:
1424	return avs_soc_component_register(adev->dev, name, &avs_component_driver, cpus, cpu_count);
1425}
1426
1427/* HD-Audio CPU DAI template */
1428static const struct snd_soc_dai_driver hda_cpu_dai = {
1429	.ops = &avs_dai_hda_be_ops,
1430	.playback = {
1431		.channels_min	= 1,
1432		.channels_max	= 8,
1433		.rates		= SNDRV_PCM_RATE_8000_192000,
1434		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1435				  SNDRV_PCM_FMTBIT_S32_LE,
1436		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1437				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1438				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1439	},
1440	.capture = {
1441		.channels_min	= 1,
1442		.channels_max	= 8,
1443		.rates		= SNDRV_PCM_RATE_8000_192000,
1444		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1445				  SNDRV_PCM_FMTBIT_S32_LE,
1446		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1447				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1448				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1449	},
1450};
1451
1452static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1453{
1454	struct snd_soc_acpi_mach *mach;
1455	struct snd_soc_dai *dai, *save;
1456	struct hda_codec *codec;
1457	char name[32];
1458
1459	mach = dev_get_platdata(component->card->dev);
1460	codec = mach->pdata;
1461	snprintf(name, sizeof(name), "%s-cpu", dev_name(&codec->core.dev));
1462
1463	for_each_component_dais_safe(component, dai, save) {
1464		int stream;
1465
1466		if (!strstr(dai->driver->name, name))
1467			continue;
1468
1469		for_each_pcm_streams(stream)
1470			snd_soc_dapm_free_widget(snd_soc_dai_get_widget(dai, stream));
1471
1472		snd_soc_unregister_dai(dai);
1473	}
1474}
1475
1476static int avs_component_hda_probe(struct snd_soc_component *component)
1477{
1478	struct snd_soc_dapm_context *dapm;
1479	struct snd_soc_dai_driver *dais;
1480	struct snd_soc_acpi_mach *mach;
1481	struct hda_codec *codec;
1482	struct hda_pcm *pcm;
1483	const char *cname;
1484	int pcm_count = 0, ret, i;
1485
1486	mach = dev_get_platdata(component->card->dev);
1487	if (!mach)
1488		return -EINVAL;
1489
1490	codec = mach->pdata;
1491	if (list_empty(&codec->pcm_list_head))
1492		return -EINVAL;
1493	list_for_each_entry(pcm, &codec->pcm_list_head, list)
1494		pcm_count++;
1495
1496	dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1497			    GFP_KERNEL);
1498	if (!dais)
1499		return -ENOMEM;
1500
1501	cname = dev_name(&codec->core.dev);
1502	dapm = snd_soc_component_get_dapm(component);
1503	pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1504
1505	for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1506		struct snd_soc_dai *dai;
1507
1508		memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1509		dais[i].id = i;
1510		dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1511					      "%s-cpu%d", cname, i);
1512		if (!dais[i].name) {
1513			ret = -ENOMEM;
1514			goto exit;
1515		}
1516
1517		if (pcm->stream[0].substreams) {
1518			dais[i].playback.stream_name =
1519				devm_kasprintf(component->dev, GFP_KERNEL,
1520					       "%s-cpu%d Tx", cname, i);
1521			if (!dais[i].playback.stream_name) {
1522				ret = -ENOMEM;
1523				goto exit;
1524			}
1525
1526			if (!hda_codec_is_display(codec)) {
1527				dais[i].playback.formats = pcm->stream[0].formats;
1528				dais[i].playback.subformats = pcm->stream[0].subformats;
1529				dais[i].playback.rates = pcm->stream[0].rates;
1530				dais[i].playback.channels_min = pcm->stream[0].channels_min;
1531				dais[i].playback.channels_max = pcm->stream[0].channels_max;
1532				dais[i].playback.sig_bits = pcm->stream[0].maxbps;
1533			}
1534		}
1535
1536		if (pcm->stream[1].substreams) {
1537			dais[i].capture.stream_name =
1538				devm_kasprintf(component->dev, GFP_KERNEL,
1539					       "%s-cpu%d Rx", cname, i);
1540			if (!dais[i].capture.stream_name) {
1541				ret = -ENOMEM;
1542				goto exit;
1543			}
1544
1545			if (!hda_codec_is_display(codec)) {
1546				dais[i].capture.formats = pcm->stream[1].formats;
1547				dais[i].capture.subformats = pcm->stream[1].subformats;
1548				dais[i].capture.rates = pcm->stream[1].rates;
1549				dais[i].capture.channels_min = pcm->stream[1].channels_min;
1550				dais[i].capture.channels_max = pcm->stream[1].channels_max;
1551				dais[i].capture.sig_bits = pcm->stream[1].maxbps;
1552			}
1553		}
1554
1555		dai = snd_soc_register_dai(component, &dais[i], false);
1556		if (!dai) {
1557			dev_err(component->dev, "register dai for %s failed\n",
1558				pcm->name);
1559			ret = -EINVAL;
1560			goto exit;
1561		}
1562
1563		ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1564		if (ret < 0) {
1565			dev_err(component->dev, "create widgets failed: %d\n",
1566				ret);
1567			goto exit;
1568		}
1569	}
1570
1571	ret = avs_component_probe(component);
1572exit:
1573	if (ret)
1574		avs_component_hda_unregister_dais(component);
1575
1576	return ret;
1577}
1578
1579static void avs_component_hda_remove(struct snd_soc_component *component)
1580{
1581	avs_component_hda_unregister_dais(component);
1582	avs_component_remove(component);
1583}
1584
1585static int avs_component_hda_open(struct snd_soc_component *component,
1586				  struct snd_pcm_substream *substream)
1587{
1588	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 
 
1589
1590	if (!rtd->dai_link->no_pcm) {
1591		struct snd_pcm_hardware hwparams = avs_pcm_hardware;
1592		struct snd_soc_pcm_runtime *be;
1593		struct snd_soc_dpcm *dpcm;
1594		int dir = substream->stream;
1595
1596		/*
1597		 * Support the DPCM reparenting while still fulfilling expectations of HDAudio
1598		 * common code - a valid stream pointer at substream->runtime->private_data -
1599		 * by having all FEs point to the same private data.
1600		 */
1601		for_each_dpcm_be(rtd, dir, dpcm) {
1602			struct snd_pcm_substream *be_substream;
1603
1604			be = dpcm->be;
1605			if (be->dpcm[dir].users == 1)
1606				break;
1607
1608			be_substream = snd_soc_dpcm_get_substream(be, dir);
1609			substream->runtime->private_data = be_substream->runtime->private_data;
1610			break;
1611		}
1612
1613		/* RESUME unsupported for de-coupled HD-Audio capture. */
1614		if (dir == SNDRV_PCM_STREAM_CAPTURE)
1615			hwparams.info &= ~SNDRV_PCM_INFO_RESUME;
1616
1617		return snd_soc_set_runtime_hwparams(substream, &hwparams);
1618	}
1619
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1620	return 0;
1621}
1622
1623static const struct snd_soc_component_driver avs_hda_component_driver = {
1624	.name			= "avs-hda-pcm",
1625	.probe			= avs_component_hda_probe,
1626	.remove			= avs_component_hda_remove,
1627	.suspend		= avs_component_suspend,
1628	.resume			= avs_component_resume,
1629	.open			= avs_component_hda_open,
 
1630	.pointer		= avs_component_pointer,
1631	.mmap			= avs_component_mmap,
1632	.pcm_construct		= avs_component_construct,
1633	/*
1634	 * hda platform component's probe() is dependent on
1635	 * codec->pcm_list_head, it needs to be initialized after codec
1636	 * component. remove_order is here for completeness sake
1637	 */
1638	.probe_order		= SND_SOC_COMP_ORDER_LATE,
1639	.remove_order		= SND_SOC_COMP_ORDER_EARLY,
1640	.module_get_upon_open	= 1,
1641	.topology_name_prefix	= "intel/avs",
1642};
1643
1644int avs_hda_platform_register(struct avs_dev *adev, const char *name)
1645{
1646	return avs_soc_component_register(adev->dev, name,
1647					  &avs_hda_component_driver, NULL, 0);
1648}
v6.8
   1// SPDX-License-Identifier: GPL-2.0-only
   2//
   3// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
   4//
   5// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
   6//          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
   7//
   8
   9#include <linux/debugfs.h>
  10#include <linux/device.h>
  11#include <sound/hda_register.h>
  12#include <sound/hdaudio_ext.h>
  13#include <sound/pcm_params.h>
  14#include <sound/soc-acpi.h>
  15#include <sound/soc-acpi-intel-match.h>
  16#include <sound/soc-component.h>
  17#include "avs.h"
  18#include "path.h"
 
  19#include "topology.h"
  20#include "../../codecs/hda.h"
  21
  22struct avs_dma_data {
  23	struct avs_tplg_path_template *template;
  24	struct avs_path *path;
  25	/*
  26	 * link stream is stored within substream's runtime
  27	 * private_data to fulfill the needs of codec BE path
  28	 *
  29	 * host stream assigned
  30	 */
  31	struct hdac_ext_stream *host_stream;
  32
 
  33	struct snd_pcm_substream *substream;
  34};
  35
  36static struct avs_tplg_path_template *
  37avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
  38{
  39	struct snd_soc_dapm_widget *dw = snd_soc_dai_get_widget(dai, direction);
  40	struct snd_soc_dapm_path *dp;
  41	enum snd_soc_dapm_direction dir;
  42
  43	if (direction == SNDRV_PCM_STREAM_CAPTURE) {
  44		dir = is_fe ? SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN;
  45	} else {
  46		dir = is_fe ? SND_SOC_DAPM_DIR_IN : SND_SOC_DAPM_DIR_OUT;
  47	}
  48
  49	dp = list_first_entry_or_null(&dw->edges[dir], typeof(*dp), list_node[dir]);
  50	if (!dp)
  51		return NULL;
  52
  53	/* Get the other widget, with actual path template data */
  54	dw = (dp->source == dw) ? dp->sink : dp->source;
  55
  56	return dw->priv;
  57}
  58
  59static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe,
  60			   const struct snd_soc_dai_ops *ops)
 
 
 
 
 
 
  61{
  62	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  63	struct avs_dev *adev = to_avs_dev(dai->dev);
 
 
 
 
 
 
 
 
 
  64	struct avs_tplg_path_template *template;
  65	struct avs_dma_data *data;
  66
  67	template = avs_dai_find_path_template(dai, is_fe, substream->stream);
  68	if (!template) {
  69		dev_err(dai->dev, "no %s path for dai %s, invalid tplg?\n",
  70			snd_pcm_stream_str(substream), dai->name);
  71		return -EINVAL;
  72	}
  73
  74	data = kzalloc(sizeof(*data), GFP_KERNEL);
  75	if (!data)
  76		return -ENOMEM;
  77
  78	data->substream = substream;
  79	data->template = template;
 
 
  80	snd_soc_dai_set_dma_data(dai, substream, data);
  81
  82	if (rtd->dai_link->ignore_suspend)
  83		adev->num_lp_paths++;
  84
  85	return 0;
  86}
  87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  88static int avs_dai_hw_params(struct snd_pcm_substream *substream,
  89			     struct snd_pcm_hw_params *fe_hw_params,
  90			     struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
  91			     int dma_id)
  92{
  93	struct avs_dma_data *data;
  94	struct avs_path *path;
  95	struct avs_dev *adev = to_avs_dev(dai->dev);
  96	int ret;
  97
  98	data = snd_soc_dai_get_dma_data(dai, substream);
  99
 100	dev_dbg(dai->dev, "%s FE hw_params str %p rtd %p",
 101		__func__, substream, substream->runtime);
 102	dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
 103		params_rate(fe_hw_params), params_channels(fe_hw_params),
 104		params_width(fe_hw_params), params_physical_width(fe_hw_params));
 105
 106	dev_dbg(dai->dev, "%s BE hw_params str %p rtd %p",
 107		__func__, substream, substream->runtime);
 108	dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
 109		params_rate(be_hw_params), params_channels(be_hw_params),
 110		params_width(be_hw_params), params_physical_width(be_hw_params));
 111
 112	path = avs_path_create(adev, dma_id, data->template, fe_hw_params, be_hw_params);
 113	if (IS_ERR(path)) {
 114		ret = PTR_ERR(path);
 115		dev_err(dai->dev, "create path failed: %d\n", ret);
 116		return ret;
 117	}
 118
 119	data->path = path;
 120	return 0;
 121}
 122
 123static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
 124				struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
 125				int dma_id)
 126{
 127	struct snd_pcm_hw_params *fe_hw_params = NULL;
 128	struct snd_soc_pcm_runtime *fe, *be;
 129	struct snd_soc_dpcm *dpcm;
 130
 131	be = snd_soc_substream_to_rtd(substream);
 132	for_each_dpcm_fe(be, substream->stream, dpcm) {
 133		fe = dpcm->fe;
 134		fe_hw_params = &fe->dpcm[substream->stream].hw_params;
 135	}
 136
 137	return avs_dai_hw_params(substream, fe_hw_params, be_hw_params, dai, dma_id);
 138}
 139
 140static int avs_dai_prepare(struct avs_dev *adev, struct snd_pcm_substream *substream,
 141			   struct snd_soc_dai *dai)
 142{
 143	struct avs_dma_data *data;
 144	int ret;
 145
 146	data = snd_soc_dai_get_dma_data(dai, substream);
 147	if (!data->path)
 148		return 0;
 149
 150	ret = avs_path_reset(data->path);
 151	if (ret < 0) {
 152		dev_err(dai->dev, "reset path failed: %d\n", ret);
 153		return ret;
 154	}
 155
 156	ret = avs_path_pause(data->path);
 157	if (ret < 0)
 158		dev_err(dai->dev, "pause path failed: %d\n", ret);
 159	return ret;
 160}
 161
 162static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops;
 163
 164static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 165{
 166	return avs_dai_startup(substream, dai, false, &avs_dai_nonhda_be_ops);
 167}
 168
 169static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 170{
 171	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 172	struct avs_dev *adev = to_avs_dev(dai->dev);
 173	struct avs_dma_data *data;
 174
 175	if (rtd->dai_link->ignore_suspend)
 176		adev->num_lp_paths--;
 177
 178	data = snd_soc_dai_get_dma_data(dai, substream);
 179
 180	snd_soc_dai_set_dma_data(dai, substream, NULL);
 181	kfree(data);
 182}
 183
 184static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
 185				       struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
 186{
 187	struct avs_dma_data *data;
 188
 189	data = snd_soc_dai_get_dma_data(dai, substream);
 190	if (data->path)
 191		return 0;
 192
 193	/* Actual port-id comes from topology. */
 194	return avs_dai_be_hw_params(substream, hw_params, dai, 0);
 195}
 196
 197static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 198{
 199	struct avs_dma_data *data;
 200
 201	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
 202
 203	data = snd_soc_dai_get_dma_data(dai, substream);
 204	if (data->path) {
 205		avs_path_free(data->path);
 206		data->path = NULL;
 207	}
 208
 209	return 0;
 210}
 211
 212static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 213{
 214	return avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
 215}
 216
 217static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 218				     struct snd_soc_dai *dai)
 219{
 220	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 221	struct avs_dma_data *data;
 222	int ret = 0;
 223
 224	data = snd_soc_dai_get_dma_data(dai, substream);
 225
 226	switch (cmd) {
 227	case SNDRV_PCM_TRIGGER_RESUME:
 228		if (rtd->dai_link->ignore_suspend)
 229			break;
 230		fallthrough;
 231	case SNDRV_PCM_TRIGGER_START:
 232	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 233		ret = avs_path_pause(data->path);
 234		if (ret < 0) {
 235			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 236			break;
 237		}
 238
 239		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 240		if (ret < 0)
 241			dev_err(dai->dev, "run BE path failed: %d\n", ret);
 242		break;
 243
 244	case SNDRV_PCM_TRIGGER_SUSPEND:
 245		if (rtd->dai_link->ignore_suspend)
 246			break;
 247		fallthrough;
 248	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 249	case SNDRV_PCM_TRIGGER_STOP:
 250		ret = avs_path_pause(data->path);
 251		if (ret < 0)
 252			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 253
 254		ret = avs_path_reset(data->path);
 255		if (ret < 0)
 256			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
 257		break;
 258
 259	default:
 260		ret = -EINVAL;
 261		break;
 262	}
 263
 264	return ret;
 265}
 266
 267static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
 268	.startup = avs_dai_nonhda_be_startup,
 269	.shutdown = avs_dai_nonhda_be_shutdown,
 270	.hw_params = avs_dai_nonhda_be_hw_params,
 271	.hw_free = avs_dai_nonhda_be_hw_free,
 272	.prepare = avs_dai_nonhda_be_prepare,
 273	.trigger = avs_dai_nonhda_be_trigger,
 274};
 275
 276static const struct snd_soc_dai_ops avs_dai_hda_be_ops;
 277
 278static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 279{
 280	return avs_dai_startup(substream, dai, false, &avs_dai_hda_be_ops);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 281}
 282
 283static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 284{
 285	return avs_dai_nonhda_be_shutdown(substream, dai);
 
 
 
 
 286}
 287
 288static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
 289				    struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
 290{
 291	struct avs_dma_data *data;
 292	struct hdac_ext_stream *link_stream;
 293
 294	data = snd_soc_dai_get_dma_data(dai, substream);
 295	if (data->path)
 296		return 0;
 297
 298	link_stream = substream->runtime->private_data;
 299
 300	return avs_dai_be_hw_params(substream, hw_params, dai,
 301				    hdac_stream(link_stream)->stream_tag - 1);
 302}
 303
 304static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 305{
 306	struct avs_dma_data *data;
 307	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 308	struct hdac_ext_stream *link_stream;
 309	struct hdac_ext_link *link;
 310	struct hda_codec *codec;
 311
 312	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
 313
 314	data = snd_soc_dai_get_dma_data(dai, substream);
 315	if (!data->path)
 316		return 0;
 317
 318	link_stream = substream->runtime->private_data;
 319	link_stream->link_prepared = false;
 320	avs_path_free(data->path);
 321	data->path = NULL;
 322
 323	/* clear link <-> stream mapping */
 324	codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
 325	link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
 326	if (!link)
 327		return -EINVAL;
 328
 329	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 330		snd_hdac_ext_bus_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag);
 331
 332	return 0;
 333}
 334
 335static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 336{
 337	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 338	struct snd_pcm_runtime *runtime = substream->runtime;
 339	struct snd_soc_pcm_stream *stream_info;
 340	struct hdac_ext_stream *link_stream;
 341	struct hdac_ext_link *link;
 
 342	struct hda_codec *codec;
 343	struct hdac_bus *bus;
 344	unsigned int format_val;
 345	unsigned int bits;
 346	int ret;
 347
 348	link_stream = runtime->private_data;
 
 
 349	if (link_stream->link_prepared)
 350		return 0;
 351
 352	codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
 353	bus = &codec->bus->core;
 354	stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
 355	bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
 356					   stream_info->sig_bits);
 357	format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
 358
 
 359	snd_hdac_ext_stream_reset(link_stream);
 360	snd_hdac_ext_stream_setup(link_stream, format_val);
 361
 362	link = snd_hdac_ext_bus_get_hlink_by_addr(bus, codec->core.addr);
 363	if (!link)
 364		return -EINVAL;
 365
 366	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 367		snd_hdac_ext_bus_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag);
 368
 369	ret = avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
 370	if (ret)
 371		return ret;
 372
 373	link_stream->link_prepared = true;
 374	return 0;
 375}
 376
 377static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 378				  struct snd_soc_dai *dai)
 379{
 380	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 381	struct hdac_ext_stream *link_stream;
 382	struct avs_dma_data *data;
 383	int ret = 0;
 384
 385	dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd);
 386
 387	data = snd_soc_dai_get_dma_data(dai, substream);
 388	link_stream = substream->runtime->private_data;
 389
 390	switch (cmd) {
 391	case SNDRV_PCM_TRIGGER_RESUME:
 392		if (rtd->dai_link->ignore_suspend)
 393			break;
 394		fallthrough;
 395	case SNDRV_PCM_TRIGGER_START:
 396	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 397		snd_hdac_ext_stream_start(link_stream);
 398
 399		ret = avs_path_pause(data->path);
 400		if (ret < 0) {
 401			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 402			break;
 403		}
 404
 405		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 406		if (ret < 0)
 407			dev_err(dai->dev, "run BE path failed: %d\n", ret);
 408		break;
 409
 410	case SNDRV_PCM_TRIGGER_SUSPEND:
 411		if (rtd->dai_link->ignore_suspend)
 412			break;
 413		fallthrough;
 414	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 415	case SNDRV_PCM_TRIGGER_STOP:
 416		ret = avs_path_pause(data->path);
 417		if (ret < 0)
 418			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 419
 420		snd_hdac_ext_stream_clear(link_stream);
 421
 422		ret = avs_path_reset(data->path);
 423		if (ret < 0)
 424			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
 425		break;
 426
 427	default:
 428		ret = -EINVAL;
 429		break;
 430	}
 431
 432	return ret;
 433}
 434
 435static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
 436	.startup = avs_dai_hda_be_startup,
 437	.shutdown = avs_dai_hda_be_shutdown,
 438	.hw_params = avs_dai_hda_be_hw_params,
 439	.hw_free = avs_dai_hda_be_hw_free,
 440	.prepare = avs_dai_hda_be_prepare,
 441	.trigger = avs_dai_hda_be_trigger,
 442};
 443
 444static const unsigned int rates[] = {
 445	8000, 11025, 12000, 16000,
 446	22050, 24000, 32000, 44100,
 447	48000, 64000, 88200, 96000,
 448	128000, 176400, 192000,
 449};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 450
 451static const struct snd_pcm_hw_constraint_list hw_rates = {
 452	.count = ARRAY_SIZE(rates),
 453	.list = rates,
 454	.mask = 0,
 455};
 456
 457const struct snd_soc_dai_ops avs_dai_fe_ops;
 
 
 
 
 
 
 
 
 
 458
 459static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 460{
 461	struct snd_pcm_runtime *runtime = substream->runtime;
 462	struct avs_dma_data *data;
 463	struct avs_dev *adev = to_avs_dev(dai->dev);
 464	struct hdac_bus *bus = &adev->base.core;
 465	struct hdac_ext_stream *host_stream;
 466	int ret;
 467
 468	ret = avs_dai_startup(substream, dai, true, &avs_dai_fe_ops);
 
 
 
 
 469	if (ret)
 470		return ret;
 471
 472	data = snd_soc_dai_get_dma_data(dai, substream);
 
 473
 474	host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST);
 475	if (!host_stream) {
 476		ret = -EBUSY;
 477		goto err;
 478	}
 479
 480	data->host_stream = host_stream;
 481	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 482	if (ret < 0)
 483		goto err;
 484
 485	/* avoid wrap-around with wall-clock */
 486	ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
 487	if (ret < 0)
 488		goto err;
 489
 490	ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_rates);
 491	if (ret < 0)
 492		goto err;
 493
 494	snd_pcm_set_sync(substream);
 495
 496	dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p",
 497		__func__, hdac_stream(host_stream)->stream_tag, substream);
 498
 499	return 0;
 500
 501err:
 502	kfree(data);
 503	return ret;
 504}
 505
 506static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 507{
 508	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 509	struct avs_dev *adev = to_avs_dev(dai->dev);
 510	struct avs_dma_data *data;
 511
 512	if (rtd->dai_link->ignore_suspend)
 513		adev->num_lp_paths--;
 514
 515	data = snd_soc_dai_get_dma_data(dai, substream);
 516
 517	snd_soc_dai_set_dma_data(dai, substream, NULL);
 518	snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
 519	kfree(data);
 520}
 521
 522static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
 523				struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
 524{
 525	struct snd_pcm_hw_params *be_hw_params = NULL;
 526	struct snd_soc_pcm_runtime *fe, *be;
 527	struct snd_soc_dpcm *dpcm;
 528	struct avs_dma_data *data;
 529	struct hdac_ext_stream *host_stream;
 530	int ret;
 531
 532	data = snd_soc_dai_get_dma_data(dai, substream);
 533	if (data->path)
 534		return 0;
 535
 536	host_stream = data->host_stream;
 537
 538	hdac_stream(host_stream)->bufsize = 0;
 539	hdac_stream(host_stream)->period_bytes = 0;
 540	hdac_stream(host_stream)->format_val = 0;
 541
 542	fe = snd_soc_substream_to_rtd(substream);
 543	for_each_dpcm_be(fe, substream->stream, dpcm) {
 544		be = dpcm->be;
 545		be_hw_params = &be->dpcm[substream->stream].hw_params;
 546	}
 547
 548	ret = avs_dai_hw_params(substream, hw_params, be_hw_params, dai,
 549				hdac_stream(host_stream)->stream_tag - 1);
 550	if (ret)
 551		goto create_err;
 552
 553	ret = avs_path_bind(data->path);
 554	if (ret < 0) {
 555		dev_err(dai->dev, "bind FE <-> BE failed: %d\n", ret);
 556		goto bind_err;
 557	}
 558
 559	return 0;
 560
 561bind_err:
 562	avs_path_free(data->path);
 563	data->path = NULL;
 564create_err:
 565	snd_pcm_lib_free_pages(substream);
 566	return ret;
 567}
 568
 569static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 570{
 571	struct avs_dma_data *data;
 572	struct hdac_ext_stream *host_stream;
 573	int ret;
 574
 575	dev_dbg(dai->dev, "%s fe HW_FREE str %p rtd %p",
 576		__func__, substream, substream->runtime);
 577
 578	data = snd_soc_dai_get_dma_data(dai, substream);
 579	if (!data->path)
 580		return 0;
 581
 582	host_stream = data->host_stream;
 583
 584	ret = avs_path_unbind(data->path);
 585	if (ret < 0)
 586		dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
 587
 588	avs_path_free(data->path);
 589	data->path = NULL;
 590	snd_hdac_stream_cleanup(hdac_stream(host_stream));
 591	hdac_stream(host_stream)->prepared = false;
 592
 593	return ret;
 594}
 595
 596static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 597{
 598	int ret;
 599
 600	ret = __avs_dai_fe_hw_free(substream, dai);
 601	snd_pcm_lib_free_pages(substream);
 602
 603	return ret;
 604}
 605
 606static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 607{
 608	struct snd_pcm_runtime *runtime = substream->runtime;
 609	struct snd_soc_pcm_stream *stream_info;
 610	struct avs_dma_data *data;
 611	struct avs_dev *adev = to_avs_dev(dai->dev);
 612	struct hdac_ext_stream *host_stream;
 613	unsigned int format_val;
 
 614	unsigned int bits;
 615	int ret;
 616
 617	data = snd_soc_dai_get_dma_data(dai, substream);
 618	host_stream = data->host_stream;
 619
 620	if (hdac_stream(host_stream)->prepared)
 621		return 0;
 622
 
 
 623	snd_hdac_stream_reset(hdac_stream(host_stream));
 624
 625	stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
 626	bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
 627					   stream_info->sig_bits);
 628	format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
 629
 630	ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
 631	if (ret < 0)
 632		return ret;
 633
 634	ret = snd_hdac_ext_host_stream_setup(host_stream, false);
 635	if (ret < 0)
 636		return ret;
 637
 638	ret = avs_dai_prepare(adev, substream, dai);
 639	if (ret)
 640		return ret;
 641
 642	hdac_stream(host_stream)->prepared = true;
 643	return 0;
 644}
 645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 646static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
 647{
 648	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 649	struct avs_dma_data *data;
 650	struct hdac_ext_stream *host_stream;
 651	struct hdac_bus *bus;
 652	unsigned long flags;
 653	int ret = 0;
 654
 655	data = snd_soc_dai_get_dma_data(dai, substream);
 656	host_stream = data->host_stream;
 657	bus = hdac_stream(host_stream)->bus;
 658
 659	switch (cmd) {
 660	case SNDRV_PCM_TRIGGER_RESUME:
 661		if (rtd->dai_link->ignore_suspend)
 662			break;
 663		fallthrough;
 664	case SNDRV_PCM_TRIGGER_START:
 665	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 666		spin_lock_irqsave(&bus->reg_lock, flags);
 667		snd_hdac_stream_start(hdac_stream(host_stream));
 668		spin_unlock_irqrestore(&bus->reg_lock, flags);
 669
 670		/* Timeout on DRSM poll shall not stop the resume so ignore the result. */
 671		if (cmd == SNDRV_PCM_TRIGGER_RESUME)
 672			snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
 673
 674		ret = avs_path_pause(data->path);
 675		if (ret < 0) {
 676			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
 677			break;
 678		}
 679
 680		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 681		if (ret < 0)
 682			dev_err(dai->dev, "run FE path failed: %d\n", ret);
 683
 684		break;
 685
 686	case SNDRV_PCM_TRIGGER_SUSPEND:
 687		if (rtd->dai_link->ignore_suspend)
 688			break;
 689		fallthrough;
 690	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 691	case SNDRV_PCM_TRIGGER_STOP:
 692		ret = avs_path_pause(data->path);
 693		if (ret < 0)
 694			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
 695
 696		spin_lock_irqsave(&bus->reg_lock, flags);
 697		snd_hdac_stream_stop(hdac_stream(host_stream));
 698		spin_unlock_irqrestore(&bus->reg_lock, flags);
 699
 700		ret = avs_path_reset(data->path);
 701		if (ret < 0)
 702			dev_err(dai->dev, "reset FE path failed: %d\n", ret);
 703		break;
 704
 705	default:
 706		ret = -EINVAL;
 707		break;
 708	}
 709
 710	return ret;
 711}
 712
 713const struct snd_soc_dai_ops avs_dai_fe_ops = {
 714	.startup = avs_dai_fe_startup,
 715	.shutdown = avs_dai_fe_shutdown,
 716	.hw_params = avs_dai_fe_hw_params,
 717	.hw_free = avs_dai_fe_hw_free,
 718	.prepare = avs_dai_fe_prepare,
 719	.trigger = avs_dai_fe_trigger,
 720};
 721
 722static ssize_t topology_name_read(struct file *file, char __user *user_buf, size_t count,
 723				  loff_t *ppos)
 724{
 725	struct snd_soc_component *component = file->private_data;
 726	struct snd_soc_card *card = component->card;
 727	struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
 728	char buf[64];
 729	size_t len;
 730
 731	len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
 732			mach->tplg_filename);
 733
 734	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 735}
 736
 737static const struct file_operations topology_name_fops = {
 738	.open = simple_open,
 739	.read = topology_name_read,
 740	.llseek = default_llseek,
 741};
 742
 743static int avs_component_load_libraries(struct avs_soc_component *acomp)
 744{
 745	struct avs_tplg *tplg = acomp->tplg;
 746	struct avs_dev *adev = to_avs_dev(acomp->base.dev);
 747	int ret;
 748
 749	if (!tplg->num_libs)
 750		return 0;
 751
 752	/* Parent device may be asleep and library loading involves IPCs. */
 753	ret = pm_runtime_resume_and_get(adev->dev);
 754	if (ret < 0)
 755		return ret;
 756
 757	avs_hda_power_gating_enable(adev, false);
 758	avs_hda_clock_gating_enable(adev, false);
 759	avs_hda_l1sen_enable(adev, false);
 760
 761	ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
 762
 763	avs_hda_l1sen_enable(adev, true);
 764	avs_hda_clock_gating_enable(adev, true);
 765	avs_hda_power_gating_enable(adev, true);
 766
 767	if (!ret)
 768		ret = avs_module_info_init(adev, false);
 769
 770	pm_runtime_mark_last_busy(adev->dev);
 771	pm_runtime_put_autosuspend(adev->dev);
 772
 773	return ret;
 774}
 775
 776static int avs_component_probe(struct snd_soc_component *component)
 777{
 778	struct snd_soc_card *card = component->card;
 779	struct snd_soc_acpi_mach *mach;
 780	struct avs_soc_component *acomp;
 781	struct avs_dev *adev;
 782	char *filename;
 783	int ret;
 784
 785	dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
 786	mach = dev_get_platdata(card->dev);
 787	acomp = to_avs_soc_component(component);
 788	adev = to_avs_dev(component->dev);
 789
 790	acomp->tplg = avs_tplg_new(component);
 791	if (!acomp->tplg)
 792		return -ENOMEM;
 793
 794	if (!mach->tplg_filename)
 795		goto finalize;
 796
 797	/* Load specified topology and create debugfs for it. */
 798	filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
 799			     mach->tplg_filename);
 800	if (!filename)
 801		return -ENOMEM;
 802
 803	ret = avs_load_topology(component, filename);
 804	kfree(filename);
 805	if (ret == -ENOENT && !strncmp(mach->tplg_filename, "hda-", 4)) {
 806		unsigned int vendor_id;
 807
 808		if (sscanf(mach->tplg_filename, "hda-%08x-tplg.bin", &vendor_id) != 1)
 809			return ret;
 810
 811		if (((vendor_id >> 16) & 0xFFFF) == 0x8086)
 812			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
 813							     "hda-8086-generic-tplg.bin");
 814		else
 815			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
 816							     "hda-generic-tplg.bin");
 817
 818		filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
 819				     mach->tplg_filename);
 820		if (!filename)
 821			return -ENOMEM;
 822
 823		dev_info(card->dev, "trying to load fallback topology %s\n", mach->tplg_filename);
 824		ret = avs_load_topology(component, filename);
 825		kfree(filename);
 826	}
 827	if (ret < 0)
 828		return ret;
 829
 830	ret = avs_component_load_libraries(acomp);
 831	if (ret < 0) {
 832		dev_err(card->dev, "libraries loading failed: %d\n", ret);
 833		goto err_load_libs;
 834	}
 835
 836finalize:
 837	debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
 838			    &topology_name_fops);
 839
 840	mutex_lock(&adev->comp_list_mutex);
 841	list_add_tail(&acomp->node, &adev->comp_list);
 842	mutex_unlock(&adev->comp_list_mutex);
 843
 844	return 0;
 845
 846err_load_libs:
 847	avs_remove_topology(component);
 848	return ret;
 849}
 850
 851static void avs_component_remove(struct snd_soc_component *component)
 852{
 853	struct avs_soc_component *acomp = to_avs_soc_component(component);
 854	struct snd_soc_acpi_mach *mach;
 855	struct avs_dev *adev = to_avs_dev(component->dev);
 856	int ret;
 857
 858	mach = dev_get_platdata(component->card->dev);
 859
 860	mutex_lock(&adev->comp_list_mutex);
 861	list_del(&acomp->node);
 862	mutex_unlock(&adev->comp_list_mutex);
 863
 864	if (mach->tplg_filename) {
 865		ret = avs_remove_topology(component);
 866		if (ret < 0)
 867			dev_err(component->dev, "unload topology failed: %d\n", ret);
 868	}
 869}
 870
 871static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data)
 872{
 873	struct snd_pcm_substream *substream;
 874	struct snd_soc_pcm_runtime *rtd;
 875	int ret;
 876
 877	substream = data->substream;
 878	rtd = snd_soc_substream_to_rtd(substream);
 879
 880	ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai);
 881	if (ret)
 882		dev_err(dai->dev, "hw_params on resume failed: %d\n", ret);
 883
 884	return ret;
 885}
 886
 887static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
 888{
 889	struct hdac_ext_stream *host_stream;
 890	struct hdac_stream *hstream;
 891	struct hdac_bus *bus;
 892	int ret;
 893
 894	host_stream = data->host_stream;
 895	hstream = hdac_stream(host_stream);
 896	bus = hdac_stream(host_stream)->bus;
 897
 898	/* Set DRSM before programming stream and position registers. */
 899	snd_hdac_stream_drsm_enable(bus, true, hstream->index);
 900
 901	ret = dai->driver->ops->prepare(data->substream, dai);
 902	if (ret) {
 903		dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret);
 904		return ret;
 905	}
 906
 907	writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL);
 908	writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU);
 909	writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL);
 910	writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU);
 911
 912	/* As per HW spec recommendation, program LPIB and DPIB to the same value. */
 913	snd_hdac_stream_set_lpib(hstream, hstream->lpib);
 914	snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
 915
 916	return 0;
 917}
 918
 919static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
 920{
 921	int ret;
 922
 923	ret = dai->driver->ops->prepare(data->substream, dai);
 924	if (ret)
 925		dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret);
 926
 927	return ret;
 928}
 929
 930static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
 931{
 932	struct hdac_ext_stream *host_stream;
 933	int ret;
 934
 935	host_stream = data->host_stream;
 936
 937	/* Store position addresses so we can resume from them later on. */
 938	hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream));
 939	host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL);
 940	host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU);
 941	host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL);
 942	host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU);
 943
 944	ret = __avs_dai_fe_hw_free(data->substream, dai);
 945	if (ret < 0)
 946		dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret);
 947
 948	return ret;
 949}
 950
 951static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
 952{
 953	int ret;
 954
 955	ret = dai->driver->ops->hw_free(data->substream, dai);
 956	if (ret < 0)
 957		dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret);
 958
 959	return ret;
 960}
 961
 962static int avs_component_pm_op(struct snd_soc_component *component, bool be,
 963			       int (*op)(struct snd_soc_dai *, struct avs_dma_data *))
 964{
 965	struct snd_soc_pcm_runtime *rtd;
 966	struct avs_dma_data *data;
 967	struct snd_soc_dai *dai;
 968	int ret;
 969
 970	for_each_component_dais(component, dai) {
 971		data = snd_soc_dai_dma_data_get_playback(dai);
 972		if (data) {
 973			rtd = snd_soc_substream_to_rtd(data->substream);
 974			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
 975				ret = op(dai, data);
 976				if (ret < 0) {
 977					__snd_pcm_set_state(data->substream->runtime,
 978							    SNDRV_PCM_STATE_DISCONNECTED);
 979					return ret;
 980				}
 981			}
 982		}
 983
 984		data = snd_soc_dai_dma_data_get_capture(dai);
 985		if (data) {
 986			rtd = snd_soc_substream_to_rtd(data->substream);
 987			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
 988				ret = op(dai, data);
 989				if (ret < 0) {
 990					__snd_pcm_set_state(data->substream->runtime,
 991							    SNDRV_PCM_STATE_DISCONNECTED);
 992					return ret;
 993				}
 994			}
 995		}
 996	}
 997
 998	return 0;
 999}
1000
1001static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be)
1002{
1003	return avs_component_pm_op(component, be, &avs_dai_resume_hw_params);
1004}
1005
1006static int avs_component_resume_prepare(struct snd_soc_component *component, bool be)
1007{
1008	int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1009
1010	if (be)
1011		prepare_cb = &avs_dai_resume_be_prepare;
1012	else
1013		prepare_cb = &avs_dai_resume_fe_prepare;
1014
1015	return avs_component_pm_op(component, be, prepare_cb);
1016}
1017
1018static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be)
1019{
1020	int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1021
1022	if (be)
1023		hw_free_cb = &avs_dai_suspend_be_hw_free;
1024	else
1025		hw_free_cb = &avs_dai_suspend_fe_hw_free;
1026
1027	return avs_component_pm_op(component, be, hw_free_cb);
1028}
1029
1030static int avs_component_suspend(struct snd_soc_component *component)
1031{
1032	int ret;
1033
1034	/*
1035	 * When freeing paths, FEs need to be first as they perform
1036	 * path unbinding.
1037	 */
1038	ret = avs_component_suspend_hw_free(component, false);
1039	if (ret)
1040		return ret;
1041
1042	return avs_component_suspend_hw_free(component, true);
1043}
1044
1045static int avs_component_resume(struct snd_soc_component *component)
1046{
1047	int ret;
1048
1049	/*
1050	 * When creating paths, FEs need to be last as they perform
1051	 * path binding.
1052	 */
1053	ret = avs_component_resume_hw_params(component, true);
1054	if (ret)
1055		return ret;
1056
1057	ret = avs_component_resume_hw_params(component, false);
1058	if (ret)
1059		return ret;
1060
1061	/* It is expected that the LINK stream is prepared first. */
1062	ret = avs_component_resume_prepare(component, true);
1063	if (ret)
1064		return ret;
1065
1066	return avs_component_resume_prepare(component, false);
1067}
1068
1069static const struct snd_pcm_hardware avs_pcm_hardware = {
1070	.info			= SNDRV_PCM_INFO_MMAP |
1071				  SNDRV_PCM_INFO_MMAP_VALID |
1072				  SNDRV_PCM_INFO_INTERLEAVED |
1073				  SNDRV_PCM_INFO_PAUSE |
1074				  SNDRV_PCM_INFO_RESUME |
1075				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
1076	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
1077				  SNDRV_PCM_FMTBIT_S32_LE,
1078	.subformats		= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1079				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1080				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1081	.buffer_bytes_max	= AZX_MAX_BUF_SIZE,
1082	.period_bytes_min	= 128,
1083	.period_bytes_max	= AZX_MAX_BUF_SIZE / 2,
1084	.periods_min		= 2,
1085	.periods_max		= AZX_MAX_FRAG,
1086	.fifo_size		= 0,
1087};
1088
1089static int avs_component_open(struct snd_soc_component *component,
1090			      struct snd_pcm_substream *substream)
1091{
1092	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1093
1094	/* only FE DAI links are handled here */
1095	if (rtd->dai_link->no_pcm)
1096		return 0;
1097
1098	return snd_soc_set_runtime_hwparams(substream, &avs_pcm_hardware);
1099}
1100
1101static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
1102{
1103	return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1104		     (AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
1105}
1106
1107static snd_pcm_uframes_t
1108avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
1109{
1110	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1111	struct avs_dma_data *data;
1112	struct hdac_ext_stream *host_stream;
1113	unsigned int pos;
1114
1115	data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0), substream);
1116	if (!data->host_stream)
1117		return 0;
1118
1119	host_stream = data->host_stream;
1120	pos = avs_hda_stream_dpib_read(host_stream);
1121
1122	if (pos >= hdac_stream(host_stream)->bufsize)
1123		pos = 0;
1124
1125	return bytes_to_frames(substream->runtime, pos);
1126}
1127
1128static int avs_component_mmap(struct snd_soc_component *component,
1129			      struct snd_pcm_substream *substream,
1130			      struct vm_area_struct *vma)
1131{
1132	return snd_pcm_lib_default_mmap(substream, vma);
1133}
1134
1135#define MAX_PREALLOC_SIZE	(32 * 1024 * 1024)
1136
1137static int avs_component_construct(struct snd_soc_component *component,
1138				   struct snd_soc_pcm_runtime *rtd)
1139{
1140	struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
1141	struct snd_pcm *pcm = rtd->pcm;
1142
1143	if (dai->driver->playback.channels_min)
1144		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
1145					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1146					   MAX_PREALLOC_SIZE);
1147
1148	if (dai->driver->capture.channels_min)
1149		snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
1150					   SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1151					   MAX_PREALLOC_SIZE);
1152
1153	return 0;
1154}
1155
1156static const struct snd_soc_component_driver avs_component_driver = {
1157	.name			= "avs-pcm",
1158	.probe			= avs_component_probe,
1159	.remove			= avs_component_remove,
1160	.suspend		= avs_component_suspend,
1161	.resume			= avs_component_resume,
1162	.open			= avs_component_open,
1163	.pointer		= avs_component_pointer,
1164	.mmap			= avs_component_mmap,
1165	.pcm_construct		= avs_component_construct,
1166	.module_get_upon_open	= 1, /* increment refcount when a pcm is opened */
1167	.topology_name_prefix	= "intel/avs",
1168};
1169
1170int avs_soc_component_register(struct device *dev, const char *name,
1171			       const struct snd_soc_component_driver *drv,
1172			       struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
1173{
1174	struct avs_soc_component *acomp;
1175	int ret;
1176
1177	acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
1178	if (!acomp)
1179		return -ENOMEM;
1180
1181	ret = snd_soc_component_initialize(&acomp->base, drv, dev);
1182	if (ret < 0)
1183		return ret;
1184
1185	/* force name change after ASoC is done with its init */
1186	acomp->base.name = name;
1187	INIT_LIST_HEAD(&acomp->node);
1188
1189	return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
1190}
1191
1192static struct snd_soc_dai_driver dmic_cpu_dais[] = {
1193{
1194	.name = "DMIC Pin",
1195	.ops = &avs_dai_nonhda_be_ops,
1196	.capture = {
1197		.stream_name	= "DMIC Rx",
1198		.channels_min	= 1,
1199		.channels_max	= 4,
1200		.rates		= SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
1201		.formats	= SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
1202	},
1203},
1204{
1205	.name = "DMIC WoV Pin",
1206	.ops = &avs_dai_nonhda_be_ops,
1207	.capture = {
1208		.stream_name	= "DMIC WoV Rx",
1209		.channels_min	= 1,
1210		.channels_max	= 4,
1211		.rates		= SNDRV_PCM_RATE_16000,
1212		.formats	= SNDRV_PCM_FMTBIT_S16_LE,
1213	},
1214},
1215};
1216
1217int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
1218{
1219	return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
1220					  ARRAY_SIZE(dmic_cpu_dais));
1221}
1222
1223static const struct snd_soc_dai_driver i2s_dai_template = {
1224	.ops = &avs_dai_nonhda_be_ops,
1225	.playback = {
1226		.channels_min	= 1,
1227		.channels_max	= 8,
1228		.rates		= SNDRV_PCM_RATE_8000_192000 |
1229				  SNDRV_PCM_RATE_KNOT,
 
 
1230		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1231				  SNDRV_PCM_FMTBIT_S32_LE,
1232		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1233				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1234				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1235	},
1236	.capture = {
1237		.channels_min	= 1,
1238		.channels_max	= 8,
1239		.rates		= SNDRV_PCM_RATE_8000_192000 |
1240				  SNDRV_PCM_RATE_KNOT,
 
 
1241		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1242				  SNDRV_PCM_FMTBIT_S32_LE,
1243		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1244				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1245				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1246	},
1247};
1248
1249int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
1250			      unsigned long *tdms)
1251{
1252	struct snd_soc_dai_driver *cpus, *dai;
1253	size_t ssp_count, cpu_count;
1254	int i, j;
1255
1256	ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
1257
1258	cpu_count = 0;
1259	for_each_set_bit(i, &port_mask, ssp_count)
1260		if (!tdms || test_bit(0, &tdms[i]))
1261			cpu_count++;
1262	if (tdms)
1263		for_each_set_bit(i, &port_mask, ssp_count)
1264			cpu_count += hweight_long(tdms[i]);
1265
1266	cpus = devm_kzalloc(adev->dev, sizeof(*cpus) * cpu_count, GFP_KERNEL);
1267	if (!cpus)
1268		return -ENOMEM;
1269
1270	dai = cpus;
1271	for_each_set_bit(i, &port_mask, ssp_count) {
1272		if (!tdms || test_bit(0, &tdms[i])) {
1273			memcpy(dai, &i2s_dai_template, sizeof(*dai));
1274
1275			dai->name =
1276				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
1277			dai->playback.stream_name =
1278				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
1279			dai->capture.stream_name =
1280				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
1281
1282			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1283				return -ENOMEM;
1284			dai++;
1285		}
1286	}
1287
1288	if (!tdms)
1289		goto plat_register;
1290
1291	for_each_set_bit(i, &port_mask, ssp_count) {
1292		for_each_set_bit(j, &tdms[i], ssp_count) {
1293			memcpy(dai, &i2s_dai_template, sizeof(*dai));
1294
1295			dai->name =
1296				devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
1297			dai->playback.stream_name =
1298				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
1299			dai->capture.stream_name =
1300				devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
1301
1302			if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1303				return -ENOMEM;
1304			dai++;
1305		}
1306	}
1307
1308plat_register:
1309	return avs_soc_component_register(adev->dev, name, &avs_component_driver, cpus, cpu_count);
1310}
1311
1312/* HD-Audio CPU DAI template */
1313static const struct snd_soc_dai_driver hda_cpu_dai = {
1314	.ops = &avs_dai_hda_be_ops,
1315	.playback = {
1316		.channels_min	= 1,
1317		.channels_max	= 8,
1318		.rates		= SNDRV_PCM_RATE_8000_192000,
1319		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1320				  SNDRV_PCM_FMTBIT_S32_LE,
1321		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1322				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1323				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1324	},
1325	.capture = {
1326		.channels_min	= 1,
1327		.channels_max	= 8,
1328		.rates		= SNDRV_PCM_RATE_8000_192000,
1329		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
1330				  SNDRV_PCM_FMTBIT_S32_LE,
1331		.subformats	= SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1332				  SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1333				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1334	},
1335};
1336
1337static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1338{
1339	struct snd_soc_acpi_mach *mach;
1340	struct snd_soc_dai *dai, *save;
1341	struct hda_codec *codec;
1342	char name[32];
1343
1344	mach = dev_get_platdata(component->card->dev);
1345	codec = mach->pdata;
1346	sprintf(name, "%s-cpu", dev_name(&codec->core.dev));
1347
1348	for_each_component_dais_safe(component, dai, save) {
1349		int stream;
1350
1351		if (!strstr(dai->driver->name, name))
1352			continue;
1353
1354		for_each_pcm_streams(stream)
1355			snd_soc_dapm_free_widget(snd_soc_dai_get_widget(dai, stream));
1356
1357		snd_soc_unregister_dai(dai);
1358	}
1359}
1360
1361static int avs_component_hda_probe(struct snd_soc_component *component)
1362{
1363	struct snd_soc_dapm_context *dapm;
1364	struct snd_soc_dai_driver *dais;
1365	struct snd_soc_acpi_mach *mach;
1366	struct hda_codec *codec;
1367	struct hda_pcm *pcm;
1368	const char *cname;
1369	int pcm_count = 0, ret, i;
1370
1371	mach = dev_get_platdata(component->card->dev);
1372	if (!mach)
1373		return -EINVAL;
1374
1375	codec = mach->pdata;
1376	if (list_empty(&codec->pcm_list_head))
1377		return -EINVAL;
1378	list_for_each_entry(pcm, &codec->pcm_list_head, list)
1379		pcm_count++;
1380
1381	dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1382			    GFP_KERNEL);
1383	if (!dais)
1384		return -ENOMEM;
1385
1386	cname = dev_name(&codec->core.dev);
1387	dapm = snd_soc_component_get_dapm(component);
1388	pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1389
1390	for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1391		struct snd_soc_dai *dai;
1392
1393		memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1394		dais[i].id = i;
1395		dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1396					      "%s-cpu%d", cname, i);
1397		if (!dais[i].name) {
1398			ret = -ENOMEM;
1399			goto exit;
1400		}
1401
1402		if (pcm->stream[0].substreams) {
1403			dais[i].playback.stream_name =
1404				devm_kasprintf(component->dev, GFP_KERNEL,
1405					       "%s-cpu%d Tx", cname, i);
1406			if (!dais[i].playback.stream_name) {
1407				ret = -ENOMEM;
1408				goto exit;
1409			}
1410
1411			if (!hda_codec_is_display(codec)) {
1412				dais[i].playback.formats = pcm->stream[0].formats;
1413				dais[i].playback.subformats = pcm->stream[0].subformats;
1414				dais[i].playback.rates = pcm->stream[0].rates;
1415				dais[i].playback.channels_min = pcm->stream[0].channels_min;
1416				dais[i].playback.channels_max = pcm->stream[0].channels_max;
1417				dais[i].playback.sig_bits = pcm->stream[0].maxbps;
1418			}
1419		}
1420
1421		if (pcm->stream[1].substreams) {
1422			dais[i].capture.stream_name =
1423				devm_kasprintf(component->dev, GFP_KERNEL,
1424					       "%s-cpu%d Rx", cname, i);
1425			if (!dais[i].capture.stream_name) {
1426				ret = -ENOMEM;
1427				goto exit;
1428			}
1429
1430			if (!hda_codec_is_display(codec)) {
1431				dais[i].capture.formats = pcm->stream[1].formats;
1432				dais[i].capture.subformats = pcm->stream[1].subformats;
1433				dais[i].capture.rates = pcm->stream[1].rates;
1434				dais[i].capture.channels_min = pcm->stream[1].channels_min;
1435				dais[i].capture.channels_max = pcm->stream[1].channels_max;
1436				dais[i].capture.sig_bits = pcm->stream[1].maxbps;
1437			}
1438		}
1439
1440		dai = snd_soc_register_dai(component, &dais[i], false);
1441		if (!dai) {
1442			dev_err(component->dev, "register dai for %s failed\n",
1443				pcm->name);
1444			ret = -EINVAL;
1445			goto exit;
1446		}
1447
1448		ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1449		if (ret < 0) {
1450			dev_err(component->dev, "create widgets failed: %d\n",
1451				ret);
1452			goto exit;
1453		}
1454	}
1455
1456	ret = avs_component_probe(component);
1457exit:
1458	if (ret)
1459		avs_component_hda_unregister_dais(component);
1460
1461	return ret;
1462}
1463
1464static void avs_component_hda_remove(struct snd_soc_component *component)
1465{
1466	avs_component_hda_unregister_dais(component);
1467	avs_component_remove(component);
1468}
1469
1470static int avs_component_hda_open(struct snd_soc_component *component,
1471				  struct snd_pcm_substream *substream)
1472{
1473	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1474	struct hdac_ext_stream *link_stream;
1475	struct hda_codec *codec;
1476
1477	if (!rtd->dai_link->no_pcm) {
1478		struct snd_pcm_hardware hwparams = avs_pcm_hardware;
1479		struct snd_soc_pcm_runtime *be;
1480		struct snd_soc_dpcm *dpcm;
1481		int dir = substream->stream;
1482
1483		/*
1484		 * Support the DPCM reparenting while still fulfilling expectations of HDAudio
1485		 * common code - a valid stream pointer at substream->runtime->private_data -
1486		 * by having all FEs point to the same private data.
1487		 */
1488		for_each_dpcm_be(rtd, dir, dpcm) {
1489			struct snd_pcm_substream *be_substream;
1490
1491			be = dpcm->be;
1492			if (be->dpcm[dir].users == 1)
1493				break;
1494
1495			be_substream = snd_soc_dpcm_get_substream(be, dir);
1496			substream->runtime->private_data = be_substream->runtime->private_data;
1497			break;
1498		}
1499
1500		/* RESUME unsupported for de-coupled HD-Audio capture. */
1501		if (dir == SNDRV_PCM_STREAM_CAPTURE)
1502			hwparams.info &= ~SNDRV_PCM_INFO_RESUME;
1503
1504		return snd_soc_set_runtime_hwparams(substream, &hwparams);
1505	}
1506
1507	codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
1508	link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
1509					     HDAC_EXT_STREAM_TYPE_LINK);
1510	if (!link_stream)
1511		return -EBUSY;
1512
1513	substream->runtime->private_data = link_stream;
1514	return 0;
1515}
1516
1517static int avs_component_hda_close(struct snd_soc_component *component,
1518				   struct snd_pcm_substream *substream)
1519{
1520	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1521	struct hdac_ext_stream *link_stream;
1522
1523	/* only BE DAI links are handled here */
1524	if (!rtd->dai_link->no_pcm)
1525		return 0;
1526
1527	link_stream = substream->runtime->private_data;
1528	snd_hdac_ext_stream_release(link_stream, HDAC_EXT_STREAM_TYPE_LINK);
1529	substream->runtime->private_data = NULL;
1530
1531	return 0;
1532}
1533
1534static const struct snd_soc_component_driver avs_hda_component_driver = {
1535	.name			= "avs-hda-pcm",
1536	.probe			= avs_component_hda_probe,
1537	.remove			= avs_component_hda_remove,
1538	.suspend		= avs_component_suspend,
1539	.resume			= avs_component_resume,
1540	.open			= avs_component_hda_open,
1541	.close			= avs_component_hda_close,
1542	.pointer		= avs_component_pointer,
1543	.mmap			= avs_component_mmap,
1544	.pcm_construct		= avs_component_construct,
1545	/*
1546	 * hda platform component's probe() is dependent on
1547	 * codec->pcm_list_head, it needs to be initialized after codec
1548	 * component. remove_order is here for completeness sake
1549	 */
1550	.probe_order		= SND_SOC_COMP_ORDER_LATE,
1551	.remove_order		= SND_SOC_COMP_ORDER_EARLY,
1552	.module_get_upon_open	= 1,
1553	.topology_name_prefix	= "intel/avs",
1554};
1555
1556int avs_hda_platform_register(struct avs_dev *adev, const char *name)
1557{
1558	return avs_soc_component_register(adev->dev, name,
1559					  &avs_hda_component_driver, NULL, 0);
1560}