File Index
Files and directories
Sign in
FILE

pcm.c

File preview with syntax highlighting.

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