Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   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}