brintos

brintos / linux-shallow public Read only

0
0
Text · 49.8 KiB · e9ff481 Raw
1790 lines · c
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)2//3// This file is provided under a dual BSD/GPLv2 license. When using or4// redistributing this file, you may do so under either license.5//6// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc.7//8// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>9//	    Vijendar Mukunda <Vijendar.Mukunda@amd.com>10//11 12/*13 * Machine Driver Interface for ACP HW block14 */15 16#include <sound/core.h>17#include <sound/jack.h>18#include <sound/pcm_params.h>19#include <sound/soc-dapm.h>20#include <sound/soc.h>21#include <linux/input.h>22#include <linux/module.h>23 24#include "../../codecs/rt5682.h"25#include "../../codecs/rt1019.h"26#include "../../codecs/rt5682s.h"27#include "../../codecs/nau8825.h"28#include "../../codecs/nau8821.h"29#include "acp-mach.h"30 31#define PCO_PLAT_CLK 4800000032#define RT5682_PLL_FREQ (48000 * 512)33#define DUAL_CHANNEL	234#define FOUR_CHANNEL	435#define NAU8821_CODEC_DAI	"nau8821-hifi"36#define NAU8821_BCLK		153600037#define NAU8821_FREQ_OUT	1228800038#define MAX98388_CODEC_DAI	"max98388-aif1"39 40#define TDM_MODE_ENABLE 141 42const struct dmi_system_id acp_quirk_table[] = {43	{44		/* Google skyrim proto-0 */45		.matches = {46			DMI_EXACT_MATCH(DMI_PRODUCT_FAMILY, "Google_Skyrim"),47		},48		.driver_data = (void *)TDM_MODE_ENABLE,49	},50	{}51};52EXPORT_SYMBOL_GPL(acp_quirk_table);53 54static const unsigned int channels[] = {55	DUAL_CHANNEL,56};57 58static const unsigned int rates[] = {59	48000,60};61 62static const struct snd_pcm_hw_constraint_list constraints_rates = {63	.count = ARRAY_SIZE(rates),64	.list  = rates,65	.mask = 0,66};67 68static const struct snd_pcm_hw_constraint_list constraints_channels = {69	.count = ARRAY_SIZE(channels),70	.list = channels,71	.mask = 0,72};73 74static int acp_clk_enable(struct acp_card_drvdata *drvdata,75			  unsigned int srate, unsigned int bclk_ratio)76{77	clk_set_rate(drvdata->wclk, srate);78	clk_set_rate(drvdata->bclk, srate * bclk_ratio);79 80	return clk_prepare_enable(drvdata->wclk);81}82 83/* Declare RT5682 codec components */84SND_SOC_DAILINK_DEF(rt5682,85	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));86 87static struct snd_soc_jack rt5682_jack;88static struct snd_soc_jack_pin rt5682_jack_pins[] = {89	{90		.pin = "Headphone Jack",91		.mask = SND_JACK_HEADPHONE,92	},93	{94		.pin = "Headset Mic",95		.mask = SND_JACK_MICROPHONE,96	},97};98 99static const struct snd_kcontrol_new rt5682_controls[] = {100	SOC_DAPM_PIN_SWITCH("Headphone Jack"),101	SOC_DAPM_PIN_SWITCH("Headset Mic"),102};103 104static const struct snd_soc_dapm_widget rt5682_widgets[] = {105	SND_SOC_DAPM_HP("Headphone Jack", NULL),106	SND_SOC_DAPM_MIC("Headset Mic", NULL),107};108 109static const struct snd_soc_dapm_route rt5682_map[] = {110	{ "Headphone Jack", NULL, "HPOL" },111	{ "Headphone Jack", NULL, "HPOR" },112	{ "IN1P", NULL, "Headset Mic" },113};114 115/* Define card ops for RT5682 CODEC */116static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)117{118	struct snd_soc_card *card = rtd->card;119	struct acp_card_drvdata *drvdata = card->drvdata;120	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);121	struct snd_soc_component *component = codec_dai->component;122	int ret;123 124	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);125 126	if (drvdata->hs_codec_id != RT5682)127		return -EINVAL;128 129	drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");130	drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");131 132	ret = snd_soc_dapm_new_controls(&card->dapm, rt5682_widgets,133					ARRAY_SIZE(rt5682_widgets));134	if (ret) {135		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);136		return ret;137	}138 139	ret = snd_soc_add_card_controls(card, rt5682_controls,140					ARRAY_SIZE(rt5682_controls));141	if (ret) {142		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);143		return ret;144	}145 146	ret = snd_soc_card_jack_new_pins(card, "Headset Jack",147					 SND_JACK_HEADSET | SND_JACK_LINEOUT |148					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |149					 SND_JACK_BTN_2 | SND_JACK_BTN_3,150					 &rt5682_jack,151					 rt5682_jack_pins,152					 ARRAY_SIZE(rt5682_jack_pins));153	if (ret) {154		dev_err(card->dev, "HP jack creation failed %d\n", ret);155		return ret;156	}157 158	snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);159	snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);160	snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);161	snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);162 163	ret = snd_soc_component_set_jack(component, &rt5682_jack, NULL);164	if (ret) {165		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);166		return ret;167	}168 169	return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682_map, ARRAY_SIZE(rt5682_map));170}171 172static int acp_card_hs_startup(struct snd_pcm_substream *substream)173{174	struct snd_pcm_runtime *runtime = substream->runtime;175	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);176	struct snd_soc_card *card = rtd->card;177	struct acp_card_drvdata *drvdata = card->drvdata;178	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);179	int ret;180	unsigned int fmt;181 182	if (drvdata->tdm_mode)183		fmt = SND_SOC_DAIFMT_DSP_A;184	else185		fmt = SND_SOC_DAIFMT_I2S;186 187	if (drvdata->soc_mclk)188		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;189	else190		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;191 192	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);193	if (ret < 0) {194		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);195		return ret;196	}197 198	runtime->hw.channels_max = DUAL_CHANNEL;199	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,200				      &constraints_channels);201	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,202				      &constraints_rates);203 204	return ret;205}206 207static void acp_card_shutdown(struct snd_pcm_substream *substream)208{209	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);210	struct snd_soc_card *card = rtd->card;211	struct acp_card_drvdata *drvdata = card->drvdata;212 213	if (!drvdata->soc_mclk)214		clk_disable_unprepare(drvdata->wclk);215}216 217static int acp_card_rt5682_hw_params(struct snd_pcm_substream *substream,218				      struct snd_pcm_hw_params *params)219{220	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);221	struct snd_soc_card *card = rtd->card;222	struct acp_card_drvdata *drvdata = card->drvdata;223	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);224	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);225	int ret;226	unsigned int fmt, srate, ch, format;227 228	srate = params_rate(params);229	ch = params_channels(params);230	format = params_physical_width(params);231 232	if (drvdata->tdm_mode)233		fmt = SND_SOC_DAIFMT_DSP_A;234	else235		fmt = SND_SOC_DAIFMT_I2S;236 237	if (drvdata->soc_mclk)238		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;239	else240		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;241 242	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);243	if (ret && ret != -ENOTSUPP) {244		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);245		return ret;246	}247 248	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);249	if (ret < 0) {250		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);251		return ret;252	}253 254	if (drvdata->tdm_mode) {255		/**256		 * As codec supports slot 0 and slot 1 for playback and capture.257		 */258		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);259		if (ret && ret != -ENOTSUPP) {260			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);261			return ret;262		}263 264		ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);265		if (ret < 0) {266			dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);267			return ret;268		}269	}270 271	ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,272				  PCO_PLAT_CLK, RT5682_PLL_FREQ);273	if (ret < 0) {274		dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);275		return ret;276	}277 278	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,279				     RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);280	if (ret < 0) {281		dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);282		return ret;283	}284 285	if (drvdata->tdm_mode) {286		ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,287					  6144000, 49152000);288		if (ret < 0) {289			dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);290			return ret;291		}292 293		ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1,294					     49152000, SND_SOC_CLOCK_IN);295		if (ret < 0) {296			dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);297			return ret;298		}299	}300 301	/* Set tdm/i2s1 master bclk ratio */302	ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);303	if (ret < 0) {304		dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);305		return ret;306	}307 308	if (!drvdata->soc_mclk) {309		ret = acp_clk_enable(drvdata, srate, ch * format);310		if (ret < 0) {311			dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);312			return ret;313		}314	}315 316	return 0;317}318 319static const struct snd_soc_ops acp_card_rt5682_ops = {320	.startup = acp_card_hs_startup,321	.shutdown = acp_card_shutdown,322	.hw_params = acp_card_rt5682_hw_params,323};324 325/* Define RT5682S CODEC component*/326SND_SOC_DAILINK_DEF(rt5682s,327		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1")));328 329static struct snd_soc_jack rt5682s_jack;330static struct snd_soc_jack_pin rt5682s_jack_pins[] = {331	{332		.pin = "Headphone Jack",333		.mask = SND_JACK_HEADPHONE,334	},335	{336		.pin = "Headset Mic",337		.mask = SND_JACK_MICROPHONE,338	},339};340 341static const struct snd_kcontrol_new rt5682s_controls[] = {342	SOC_DAPM_PIN_SWITCH("Headphone Jack"),343	SOC_DAPM_PIN_SWITCH("Headset Mic"),344};345 346static const struct snd_soc_dapm_widget rt5682s_widgets[] = {347	SND_SOC_DAPM_HP("Headphone Jack", NULL),348	SND_SOC_DAPM_MIC("Headset Mic", NULL),349};350 351static const struct snd_soc_dapm_route rt5682s_map[] = {352	{ "Headphone Jack", NULL, "HPOL" },353	{ "Headphone Jack", NULL, "HPOR" },354	{ "IN1P", NULL, "Headset Mic" },355};356 357static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)358{359	struct snd_soc_card *card = rtd->card;360	struct acp_card_drvdata *drvdata = card->drvdata;361	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);362	struct snd_soc_component *component = codec_dai->component;363	int ret;364 365	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);366 367	if (drvdata->hs_codec_id != RT5682S)368		return -EINVAL;369 370	if (!drvdata->soc_mclk) {371		drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");372		drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");373	}374 375	ret = snd_soc_dapm_new_controls(&card->dapm, rt5682s_widgets,376					ARRAY_SIZE(rt5682s_widgets));377	if (ret) {378		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);379		return ret;380	}381 382	ret = snd_soc_add_card_controls(card, rt5682s_controls,383					ARRAY_SIZE(rt5682s_controls));384	if (ret) {385		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);386		return ret;387	}388 389	ret = snd_soc_card_jack_new_pins(card, "Headset Jack",390					 SND_JACK_HEADSET | SND_JACK_LINEOUT |391					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |392					 SND_JACK_BTN_2 | SND_JACK_BTN_3,393					 &rt5682s_jack,394					 rt5682s_jack_pins,395					 ARRAY_SIZE(rt5682s_jack_pins));396	if (ret) {397		dev_err(card->dev, "HP jack creation failed %d\n", ret);398		return ret;399	}400 401	snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);402	snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);403	snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);404	snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);405 406	ret = snd_soc_component_set_jack(component, &rt5682s_jack, NULL);407	if (ret) {408		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);409		return ret;410	}411 412	return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map));413}414 415static int acp_card_rt5682s_hw_params(struct snd_pcm_substream *substream,416				      struct snd_pcm_hw_params *params)417{418	struct snd_soc_pcm_runtime *rtd = substream->private_data;419	struct snd_soc_card *card = rtd->card;420	struct acp_card_drvdata *drvdata = card->drvdata;421	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);422	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);423	int ret;424	unsigned int fmt, srate, ch, format;425 426	srate = params_rate(params);427	ch = params_channels(params);428	format = params_physical_width(params);429 430	if (drvdata->tdm_mode)431		fmt = SND_SOC_DAIFMT_DSP_A;432	else433		fmt = SND_SOC_DAIFMT_I2S;434 435	if (drvdata->soc_mclk)436		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;437	else438		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;439 440	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);441	if (ret && ret != -ENOTSUPP) {442		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);443		return ret;444	}445 446	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);447	if (ret < 0) {448		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);449		return ret;450	}451 452	if (drvdata->tdm_mode) {453		/**454		 * As codec supports slot 0 and slot 1 for playback and capture.455		 */456		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);457		if (ret && ret != -ENOTSUPP) {458			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);459			return ret;460		}461 462		ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);463		if (ret < 0) {464			dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);465			return ret;466		}467	}468 469	ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,470				  PCO_PLAT_CLK, RT5682_PLL_FREQ);471	if (ret < 0) {472		dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);473		return ret;474	}475 476	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,477				     RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);478	if (ret < 0) {479		dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);480		return ret;481	}482 483	if (drvdata->tdm_mode) {484		ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,485					  6144000, 49152000);486		if (ret < 0) {487			dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);488			return ret;489		}490 491		ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1,492					     49152000, SND_SOC_CLOCK_IN);493		if (ret < 0) {494			dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);495			return ret;496		}497	}498 499	/* Set tdm/i2s1 master bclk ratio */500	ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);501	if (ret < 0) {502		dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);503		return ret;504	}505 506	clk_set_rate(drvdata->wclk, srate);507	clk_set_rate(drvdata->bclk, srate * ch * format);508	if (!drvdata->soc_mclk) {509		ret = acp_clk_enable(drvdata, srate, ch * format);510		if (ret < 0) {511			dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);512			return ret;513		}514	}515 516	return 0;517}518 519static const struct snd_soc_ops acp_card_rt5682s_ops = {520	.startup = acp_card_hs_startup,521	.hw_params = acp_card_rt5682s_hw_params,522};523 524static const unsigned int dmic_channels[] = {525	DUAL_CHANNEL, FOUR_CHANNEL,526};527 528static const struct snd_pcm_hw_constraint_list dmic_constraints_channels = {529	.count = ARRAY_SIZE(dmic_channels),530	.list = dmic_channels,531	.mask = 0,532};533 534static int acp_card_dmic_startup(struct snd_pcm_substream *substream)535{536	struct snd_pcm_runtime *runtime = substream->runtime;537 538	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,539				   &dmic_constraints_channels);540	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,541				   &constraints_rates);542 543	return 0;544}545 546static const struct snd_soc_ops acp_card_dmic_ops = {547	.startup = acp_card_dmic_startup,548};549 550/* Declare RT1019 codec components */551SND_SOC_DAILINK_DEF(rt1019,552	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),553			  COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));554 555static const struct snd_kcontrol_new rt1019_controls[] = {556	SOC_DAPM_PIN_SWITCH("Left Spk"),557	SOC_DAPM_PIN_SWITCH("Right Spk"),558};559 560static const struct snd_soc_dapm_widget rt1019_widgets[] = {561	SND_SOC_DAPM_SPK("Left Spk", NULL),562	SND_SOC_DAPM_SPK("Right Spk", NULL),563};564 565static const struct snd_soc_dapm_route rt1019_map_lr[] = {566	{ "Left Spk", NULL, "Left SPO" },567	{ "Right Spk", NULL, "Right SPO" },568};569 570static struct snd_soc_codec_conf rt1019_conf[] = {571	{572		 .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),573		 .name_prefix = "Left",574	},575	{576		 .dlc = COMP_CODEC_CONF("i2c-10EC1019:00"),577		 .name_prefix = "Right",578	},579};580 581static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd)582{583	struct snd_soc_card *card = rtd->card;584	struct acp_card_drvdata *drvdata = card->drvdata;585	int ret;586 587	if (drvdata->amp_codec_id != RT1019)588		return -EINVAL;589 590	ret = snd_soc_dapm_new_controls(&card->dapm, rt1019_widgets,591					ARRAY_SIZE(rt1019_widgets));592	if (ret) {593		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);594		return ret;595	}596 597	ret = snd_soc_add_card_controls(card, rt1019_controls,598					ARRAY_SIZE(rt1019_controls));599	if (ret) {600		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);601		return ret;602	}603 604	return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr,605				       ARRAY_SIZE(rt1019_map_lr));606}607 608static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,609				     struct snd_pcm_hw_params *params)610{611	struct snd_soc_pcm_runtime *rtd = substream->private_data;612	struct snd_soc_card *card = rtd->card;613	struct acp_card_drvdata *drvdata = card->drvdata;614	struct snd_soc_dai *codec_dai;615	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);616	int i, ret = 0;617	unsigned int fmt, srate, ch, format;618 619	srate = params_rate(params);620	ch = params_channels(params);621	format = params_physical_width(params);622 623	if (drvdata->amp_codec_id != RT1019)624		return -EINVAL;625 626	if (drvdata->tdm_mode)627		fmt = SND_SOC_DAIFMT_DSP_A;628	else629		fmt = SND_SOC_DAIFMT_I2S;630 631	if (drvdata->soc_mclk)632		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;633	else634		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;635 636	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);637	if (ret && ret != -ENOTSUPP) {638		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);639		return ret;640	}641 642	if (drvdata->tdm_mode) {643		/**644		 * As codec supports slot 2 and slot 3 for playback.645		 */646		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);647		if (ret && ret != -ENOTSUPP) {648			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);649			return ret;650		}651	}652 653	for_each_rtd_codec_dais(rtd, i, codec_dai) {654		if (strcmp(codec_dai->name, "rt1019-aif"))655			continue;656 657		if (drvdata->tdm_mode)658			ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,659						  TDM_CHANNELS * format * srate, 256 * srate);660		else661			ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,662						  ch * format * srate, 256 * srate);663 664		if (ret < 0)665			return ret;666 667		ret = snd_soc_dai_set_sysclk(codec_dai, RT1019_SCLK_S_PLL,668					     256 * srate, SND_SOC_CLOCK_IN);669		if (ret < 0)670			return ret;671 672		if (drvdata->tdm_mode) {673			ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A674							| SND_SOC_DAIFMT_NB_NF);675			if (ret < 0) {676				dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);677				return ret;678			}679 680			/**681			 * As codec supports slot 2 for left channel playback.682			 */683			if (!strcmp(codec_dai->component->name, "i2c-10EC1019:00")) {684				ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x4, 8, 16);685				if (ret < 0)686					break;687			}688 689			/**690			 * As codec supports slot 3 for right channel playback.691			 */692			if (!strcmp(codec_dai->component->name, "i2c-10EC1019:01")) {693				ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x8, 8, 16);694				if (ret < 0)695					break;696			}697		}698	}699 700	if (!drvdata->soc_mclk) {701		ret = acp_clk_enable(drvdata, srate, ch * format);702		if (ret < 0) {703			dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);704			return ret;705		}706	}707 708	return 0;709}710 711static int acp_card_amp_startup(struct snd_pcm_substream *substream)712{713	struct snd_pcm_runtime *runtime = substream->runtime;714 715	runtime->hw.channels_max = DUAL_CHANNEL;716	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,717				      &constraints_channels);718	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,719				      &constraints_rates);720 721	return 0;722}723 724static const struct snd_soc_ops acp_card_rt1019_ops = {725	.startup = acp_card_amp_startup,726	.shutdown = acp_card_shutdown,727	.hw_params = acp_card_rt1019_hw_params,728};729 730/* Declare Maxim codec components */731SND_SOC_DAILINK_DEF(max98360a,732	DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi")));733 734static const struct snd_kcontrol_new max98360a_controls[] = {735	SOC_DAPM_PIN_SWITCH("Spk"),736};737 738static const struct snd_soc_dapm_widget max98360a_widgets[] = {739	SND_SOC_DAPM_SPK("Spk", NULL),740};741 742static const struct snd_soc_dapm_route max98360a_map[] = {743	{"Spk", NULL, "Speaker"},744};745 746static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd)747{748	struct snd_soc_card *card = rtd->card;749	struct acp_card_drvdata *drvdata = card->drvdata;750	int ret;751 752	if (drvdata->amp_codec_id != MAX98360A)753		return -EINVAL;754 755	ret = snd_soc_dapm_new_controls(&card->dapm, max98360a_widgets,756					ARRAY_SIZE(max98360a_widgets));757	if (ret) {758		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);759		return ret;760	}761 762	ret = snd_soc_add_card_controls(card, max98360a_controls,763					ARRAY_SIZE(max98360a_controls));764	if (ret) {765		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);766		return ret;767	}768 769	return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map,770				       ARRAY_SIZE(max98360a_map));771}772 773static int acp_card_maxim_hw_params(struct snd_pcm_substream *substream,774				    struct snd_pcm_hw_params *params)775{776	struct snd_soc_pcm_runtime *rtd = substream->private_data;777	struct snd_soc_card *card = rtd->card;778	struct acp_card_drvdata *drvdata = card->drvdata;779	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);780	unsigned int fmt, srate, ch, format;781	int ret;782 783	srate = params_rate(params);784	ch = params_channels(params);785	format = params_physical_width(params);786 787	if (drvdata->tdm_mode)788		fmt = SND_SOC_DAIFMT_DSP_A;789	else790		fmt = SND_SOC_DAIFMT_I2S;791 792	if (drvdata->soc_mclk)793		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;794	else795		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;796 797	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);798	if (ret && ret != -ENOTSUPP) {799		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);800		return ret;801	}802 803	if (drvdata->tdm_mode) {804		/**805		 * As codec supports slot 2 and slot 3 for playback.806		 */807		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);808		if (ret && ret != -ENOTSUPP) {809			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);810			return ret;811		}812	}813 814	if (!drvdata->soc_mclk) {815		ret = acp_clk_enable(drvdata, srate, ch * format);816		if (ret < 0) {817			dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);818			return ret;819		}820	}821	return 0;822}823 824static const struct snd_soc_ops acp_card_maxim_ops = {825	.startup = acp_card_amp_startup,826	.shutdown = acp_card_shutdown,827	.hw_params = acp_card_maxim_hw_params,828};829 830SND_SOC_DAILINK_DEF(max98388,831		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", MAX98388_CODEC_DAI),832				       COMP_CODEC("i2c-ADS8388:01", MAX98388_CODEC_DAI)));833 834static const struct snd_kcontrol_new max98388_controls[] = {835	SOC_DAPM_PIN_SWITCH("Left Spk"),836	SOC_DAPM_PIN_SWITCH("Right Spk"),837};838 839static const struct snd_soc_dapm_widget max98388_widgets[] = {840	SND_SOC_DAPM_SPK("Left Spk", NULL),841	SND_SOC_DAPM_SPK("Right Spk", NULL),842};843 844static const struct snd_soc_dapm_route max98388_map[] = {845	{ "Left Spk", NULL, "Left BE_OUT" },846	{ "Right Spk", NULL, "Right BE_OUT" },847};848 849static struct snd_soc_codec_conf max98388_conf[] = {850	{851		.dlc = COMP_CODEC_CONF("i2c-ADS8388:00"),852		.name_prefix = "Left",853	},854	{855		.dlc = COMP_CODEC_CONF("i2c-ADS8388:01"),856		.name_prefix = "Right",857	},858};859 860static const unsigned int max98388_format[] = {16};861 862static struct snd_pcm_hw_constraint_list constraints_sample_bits_max = {863	.list = max98388_format,864	.count = ARRAY_SIZE(max98388_format),865};866 867static int acp_card_max98388_startup(struct snd_pcm_substream *substream)868{869	struct snd_pcm_runtime *runtime = substream->runtime;870 871	runtime->hw.channels_max = DUAL_CHANNEL;872	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,873				   &constraints_channels);874	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,875				   &constraints_rates);876	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,877				   &constraints_sample_bits_max);878 879	return 0;880}881 882static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd)883{884	struct snd_soc_card *card = rtd->card;885	struct acp_card_drvdata *drvdata = card->drvdata;886	int ret;887 888	if (drvdata->amp_codec_id != MAX98388)889		return -EINVAL;890 891	ret = snd_soc_dapm_new_controls(&card->dapm, max98388_widgets,892					ARRAY_SIZE(max98388_widgets));893 894	if (ret) {895		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);896		/* Don't need to add routes if widget addition failed */897		return ret;898	}899 900	ret = snd_soc_add_card_controls(card, max98388_controls,901					ARRAY_SIZE(max98388_controls));902	if (ret) {903		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);904		return ret;905	}906 907	return snd_soc_dapm_add_routes(&rtd->card->dapm, max98388_map,908				       ARRAY_SIZE(max98388_map));909}910 911static int acp_max98388_hw_params(struct snd_pcm_substream *substream,912				  struct snd_pcm_hw_params *params)913{914	struct snd_soc_pcm_runtime *rtd = substream->private_data;915	struct snd_soc_card *card = rtd->card;916	struct snd_soc_dai *codec_dai =917			snd_soc_card_get_codec_dai(card,918						   MAX98388_CODEC_DAI);919	int ret;920 921	ret = snd_soc_dai_set_fmt(codec_dai,922				  SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S |923				  SND_SOC_DAIFMT_NB_NF);924	if (ret < 0)925		return ret;926 927	return ret;928}929 930static const struct snd_soc_ops acp_max98388_ops = {931	.startup = acp_card_max98388_startup,932	.hw_params = acp_max98388_hw_params,933};934 935/* Declare nau8825 codec components */936SND_SOC_DAILINK_DEF(nau8825,937		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi")));938 939static struct snd_soc_jack nau8825_jack;940static struct snd_soc_jack_pin nau8825_jack_pins[] = {941	{942		.pin = "Headphone Jack",943		.mask = SND_JACK_HEADPHONE,944	},945	{946		.pin = "Headset Mic",947		.mask = SND_JACK_MICROPHONE,948	},949};950 951static const struct snd_kcontrol_new nau8825_controls[] = {952	SOC_DAPM_PIN_SWITCH("Headphone Jack"),953	SOC_DAPM_PIN_SWITCH("Headset Mic"),954};955 956static const struct snd_soc_dapm_widget nau8825_widgets[] = {957	SND_SOC_DAPM_HP("Headphone Jack", NULL),958	SND_SOC_DAPM_MIC("Headset Mic", NULL),959};960 961static const struct snd_soc_dapm_route nau8825_map[] = {962	{ "Headphone Jack", NULL, "HPOL" },963	{ "Headphone Jack", NULL, "HPOR" },964};965 966static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd)967{968	struct snd_soc_card *card = rtd->card;969	struct acp_card_drvdata *drvdata = card->drvdata;970	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);971	struct snd_soc_component *component = codec_dai->component;972	int ret;973 974	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);975 976	if (drvdata->hs_codec_id != NAU8825)977		return -EINVAL;978 979	ret = snd_soc_dapm_new_controls(&card->dapm, nau8825_widgets,980					ARRAY_SIZE(nau8825_widgets));981	if (ret) {982		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);983		return ret;984	}985 986	ret = snd_soc_add_card_controls(card, nau8825_controls,987					ARRAY_SIZE(nau8825_controls));988	if (ret) {989		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);990		return ret;991	}992 993	ret = snd_soc_card_jack_new_pins(card, "Headset Jack",994					 SND_JACK_HEADSET | SND_JACK_LINEOUT |995					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |996					 SND_JACK_BTN_2 | SND_JACK_BTN_3,997					 &nau8825_jack,998					 nau8825_jack_pins,999					 ARRAY_SIZE(nau8825_jack_pins));1000	if (ret) {1001		dev_err(card->dev, "HP jack creation failed %d\n", ret);1002		return ret;1003	}1004 1005	snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);1006	snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);1007	snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);1008	snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);1009 1010	ret = snd_soc_component_set_jack(component, &nau8825_jack, NULL);1011	if (ret) {1012		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);1013		return ret;1014	}1015 1016	return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8825_map, ARRAY_SIZE(nau8825_map));1017}1018 1019static int acp_nau8825_hw_params(struct snd_pcm_substream *substream,1020				 struct snd_pcm_hw_params *params)1021{1022	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);1023	struct snd_soc_card *card = rtd->card;1024	struct acp_card_drvdata *drvdata = card->drvdata;1025	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);1026	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);1027	int ret;1028	unsigned int fmt;1029 1030	ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS,1031				     (48000 * 256), SND_SOC_CLOCK_IN);1032	if (ret < 0)1033		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);1034 1035	ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params),1036				  params_rate(params) * 256);1037	if (ret < 0) {1038		dev_err(rtd->dev, "can't set FLL: %d\n", ret);1039		return ret;1040	}1041 1042	if (drvdata->tdm_mode)1043		fmt = SND_SOC_DAIFMT_DSP_A;1044	else1045		fmt = SND_SOC_DAIFMT_I2S;1046 1047	if (drvdata->soc_mclk)1048		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;1049	else1050		fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;1051 1052	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);1053	if (ret && ret != -ENOTSUPP) {1054		dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);1055		return ret;1056	}1057 1058	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);1059	if (ret < 0) {1060		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);1061		return ret;1062	}1063 1064	if (drvdata->tdm_mode) {1065		/**1066		 * As codec supports slot 4 and slot 5 for playback and slot 6 for capture.1067		 */1068		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x30, 0xC0, 8, 16);1069		if (ret && ret != -ENOTSUPP) {1070			dev_err(rtd->dev, "set TDM slot err: %d\n", ret);1071			return ret;1072		}1073 1074		ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x40, 0x30, 8, 16);1075		if (ret < 0) {1076			dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);1077			return ret;1078		}1079	}1080	return ret;1081}1082 1083static int acp_nau8825_startup(struct snd_pcm_substream *substream)1084{1085	struct snd_pcm_runtime *runtime = substream->runtime;1086 1087	runtime->hw.channels_max = 2;1088	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,1089				   &constraints_channels);1090 1091	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;1092	snd_pcm_hw_constraint_list(runtime, 0,1093				   SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);1094	return 0;1095}1096 1097static const struct snd_soc_ops acp_card_nau8825_ops = {1098	.startup =  acp_nau8825_startup,1099	.hw_params = acp_nau8825_hw_params,1100};1101 1102static int platform_clock_control(struct snd_soc_dapm_widget *w,1103				  struct snd_kcontrol *k, int  event)1104{1105	struct snd_soc_dapm_context *dapm = w->dapm;1106	struct snd_soc_card *card = dapm->card;1107	struct snd_soc_dai *codec_dai;1108	int ret = 0;1109 1110	codec_dai = snd_soc_card_get_codec_dai(card, NAU8821_CODEC_DAI);1111	if (!codec_dai) {1112		dev_err(card->dev, "Codec dai not found\n");1113		return -EIO;1114	}1115 1116	if (SND_SOC_DAPM_EVENT_OFF(event)) {1117		ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_INTERNAL,1118					     0, SND_SOC_CLOCK_IN);1119		if (ret < 0) {1120			dev_err(card->dev, "set sysclk err = %d\n", ret);1121			return -EIO;1122		}1123	} else {1124		ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,1125					     SND_SOC_CLOCK_IN);1126		if (ret < 0)1127			dev_err(codec_dai->dev, "can't set FS clock %d\n", ret);1128		ret = snd_soc_dai_set_pll(codec_dai, 0, 0, NAU8821_BCLK,1129					  NAU8821_FREQ_OUT);1130		if (ret < 0)1131			dev_err(codec_dai->dev, "can't set FLL: %d\n", ret);1132	}1133	return ret;1134}1135 1136static struct snd_soc_jack nau8821_jack;1137static struct snd_soc_jack_pin nau8821_jack_pins[] = {1138	{1139		.pin = "Headphone Jack",1140		.mask = SND_JACK_HEADPHONE,1141	},1142	{1143		.pin = "Headset Mic",1144		.mask = SND_JACK_MICROPHONE,1145	},1146};1147 1148static const struct snd_kcontrol_new nau8821_controls[] = {1149	SOC_DAPM_PIN_SWITCH("Headphone Jack"),1150	SOC_DAPM_PIN_SWITCH("Headset Mic"),1151};1152 1153static const struct snd_soc_dapm_widget nau8821_widgets[] = {1154	SND_SOC_DAPM_HP("Headphone Jack", NULL),1155	SND_SOC_DAPM_MIC("Headset Mic", NULL),1156	SND_SOC_DAPM_MIC("Int Mic", NULL),1157	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,1158			    platform_clock_control, SND_SOC_DAPM_PRE_PMU |1159			    SND_SOC_DAPM_POST_PMD),1160};1161 1162static const struct snd_soc_dapm_route nau8821_audio_route[] = {1163	/* HP jack connectors - unknown if we have jack detection */1164	{ "Headphone Jack", NULL, "HPOL" },1165	{ "Headphone Jack", NULL, "HPOR" },1166	{ "MICL", NULL, "Headset Mic" },1167	{ "MICR", NULL, "Headset Mic" },1168	{ "DMIC", NULL, "Int Mic" },1169	{ "Headphone Jack", NULL, "Platform Clock" },1170	{ "Headset Mic", NULL, "Platform Clock" },1171	{ "Int Mic", NULL, "Platform Clock" },1172};1173 1174static const unsigned int nau8821_format[] = {16};1175 1176static struct snd_pcm_hw_constraint_list constraints_sample_bits = {1177	.list = nau8821_format,1178	.count = ARRAY_SIZE(nau8821_format),1179};1180 1181static int acp_8821_init(struct snd_soc_pcm_runtime *rtd)1182{1183	struct snd_soc_card *card = rtd->card;1184	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);1185	struct snd_soc_component *component = codec_dai->component;1186	int ret;1187 1188	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);1189 1190	ret = snd_soc_dapm_new_controls(&card->dapm, nau8821_widgets,1191					ARRAY_SIZE(nau8821_widgets));1192	if (ret) {1193		dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);1194		// Don't need to add routes if widget addition failed1195		return ret;1196	}1197 1198	ret = snd_soc_add_card_controls(card, nau8821_controls,1199					ARRAY_SIZE(nau8821_controls));1200	if (ret) {1201		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);1202		return ret;1203	}1204 1205	ret = snd_soc_card_jack_new_pins(card, "Headset Jack",1206					 SND_JACK_HEADSET | SND_JACK_LINEOUT |1207					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |1208					 SND_JACK_BTN_2 | SND_JACK_BTN_3,1209					 &nau8821_jack,1210					 nau8821_jack_pins,1211					 ARRAY_SIZE(nau8821_jack_pins));1212	if (ret) {1213		dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);1214		return ret;1215	}1216 1217	snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);1218	snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);1219	snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);1220	snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);1221 1222	nau8821_enable_jack_detect(component, &nau8821_jack);1223 1224	return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8821_audio_route,1225				       ARRAY_SIZE(nau8821_audio_route));1226}1227 1228static int acp_8821_startup(struct snd_pcm_substream *substream)1229{1230	struct snd_pcm_runtime *runtime = substream->runtime;1231 1232	runtime->hw.channels_max = DUAL_CHANNEL;1233	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,1234				   &constraints_channels);1235	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,1236				   &constraints_rates);1237	snd_pcm_hw_constraint_list(substream->runtime, 0,1238				   SNDRV_PCM_HW_PARAM_SAMPLE_BITS,1239				   &constraints_sample_bits);1240	return 0;1241}1242 1243static int acp_nau8821_hw_params(struct snd_pcm_substream *substream,1244				 struct snd_pcm_hw_params *params)1245{1246	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);1247	struct snd_soc_card *card = rtd->card;1248	struct acp_card_drvdata *drvdata = card->drvdata;1249	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);1250	int ret;1251	unsigned int fmt;1252 1253	if (drvdata->soc_mclk)1254		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;1255	else1256		fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;1257 1258	ret =  snd_soc_dai_set_fmt(codec_dai, fmt);1259	if (ret < 0) {1260		dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);1261		return ret;1262	}1263 1264	ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,1265				     SND_SOC_CLOCK_IN);1266	if (ret < 0)1267		dev_err(card->dev, "can't set FS clock %d\n", ret);1268	ret = snd_soc_dai_set_pll(codec_dai, 0, 0, snd_soc_params_to_bclk(params),1269				  params_rate(params) * 256);1270	if (ret < 0)1271		dev_err(card->dev, "can't set FLL: %d\n", ret);1272 1273	return ret;1274}1275 1276static const struct snd_soc_ops acp_8821_ops = {1277	.startup = acp_8821_startup,1278	.hw_params = acp_nau8821_hw_params,1279};1280 1281SND_SOC_DAILINK_DEF(nau8821,1282		    DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00",1283						  NAU8821_CODEC_DAI)));1284 1285/* Declare DMIC codec components */1286SND_SOC_DAILINK_DEF(dmic_codec,1287		DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));1288 1289/* Declare ACP CPU components */1290static struct snd_soc_dai_link_component platform_component[] = {1291	{1292		 .name = "acp_asoc_renoir.0",1293	}1294};1295 1296static struct snd_soc_dai_link_component platform_rmb_component[] = {1297	{1298		.name = "acp_asoc_rembrandt.0",1299	}1300};1301 1302static struct snd_soc_dai_link_component platform_acp63_component[] = {1303	{1304		.name = "acp_asoc_acp63.0",1305	}1306};1307 1308static struct snd_soc_dai_link_component platform_acp70_component[] = {1309	{1310		.name = "acp_asoc_acp70.0",1311	}1312};1313 1314static struct snd_soc_dai_link_component sof_component[] = {1315	{1316		 .name = "0000:04:00.5",1317	}1318};1319 1320SND_SOC_DAILINK_DEF(i2s_sp,1321	DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp")));1322SND_SOC_DAILINK_DEF(i2s_hs,1323		    DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs")));1324SND_SOC_DAILINK_DEF(sof_sp,1325	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp")));1326SND_SOC_DAILINK_DEF(sof_sp_virtual,1327	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp-virtual")));1328SND_SOC_DAILINK_DEF(sof_hs,1329		    DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs")));1330SND_SOC_DAILINK_DEF(sof_hs_virtual,1331	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs-virtual")));1332SND_SOC_DAILINK_DEF(sof_bt,1333		    DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-bt")));1334SND_SOC_DAILINK_DEF(sof_dmic,1335	DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic")));1336SND_SOC_DAILINK_DEF(pdm_dmic,1337	DAILINK_COMP_ARRAY(COMP_CPU("acp-pdm-dmic")));1338 1339static int acp_rtk_set_bias_level(struct snd_soc_card *card,1340				  struct snd_soc_dapm_context *dapm,1341				  enum snd_soc_bias_level level)1342{1343	struct snd_soc_component *component = dapm->component;1344	struct acp_card_drvdata *drvdata = card->drvdata;1345	int ret = 0;1346 1347	if (!component)1348		return 0;1349 1350	if (strncmp(component->name, "i2c-RTL5682", 11) &&1351	    strncmp(component->name, "i2c-10EC1019", 12))1352		return 0;1353 1354	/*1355	 * For Realtek's codec and amplifier components,1356	 * the lrck and bclk must be enabled brfore their all dapms be powered on,1357	 * and must be disabled after their all dapms be powered down1358	 * to avoid any pop.1359	 */1360	switch (level) {1361	case SND_SOC_BIAS_STANDBY:1362		if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {1363 1364			/* Increase bclk's enable_count */1365			ret = clk_prepare_enable(drvdata->bclk);1366			if (ret < 0)1367				dev_err(component->dev, "Failed to enable bclk %d\n", ret);1368		} else {1369			/*1370			 * Decrease bclk's enable_count.1371			 * While the enable_count is 0, the bclk would be closed.1372			 */1373			clk_disable_unprepare(drvdata->bclk);1374		}1375		break;1376	default:1377		break;1378	}1379 1380	return ret;1381}1382 1383int acp_sofdsp_dai_links_create(struct snd_soc_card *card)1384{1385	struct snd_soc_dai_link *links;1386	struct device *dev = card->dev;1387	struct acp_card_drvdata *drv_data = card->drvdata;1388	int i = 0, num_links = 0;1389 1390	if (drv_data->hs_cpu_id)1391		num_links++;1392	if (drv_data->bt_cpu_id)1393		num_links++;1394	if (drv_data->amp_cpu_id)1395		num_links++;1396	if (drv_data->dmic_cpu_id)1397		num_links++;1398 1399	links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);1400	if (!links)1401		return -ENOMEM;1402 1403	if (drv_data->hs_cpu_id == I2S_SP) {1404		links[i].name = "acp-headset-codec";1405		links[i].id = HEADSET_BE_ID;1406		links[i].cpus = sof_sp;1407		links[i].num_cpus = ARRAY_SIZE(sof_sp);1408		links[i].platforms = sof_component;1409		links[i].num_platforms = ARRAY_SIZE(sof_component);1410		links[i].dpcm_playback = 1;1411		links[i].dpcm_capture = 1;1412		links[i].nonatomic = true;1413		links[i].no_pcm = 1;1414		if (!drv_data->hs_codec_id) {1415			/* Use dummy codec if codec id not specified */1416			links[i].codecs = &snd_soc_dummy_dlc;1417			links[i].num_codecs = 1;1418		}1419		if (drv_data->hs_codec_id == RT5682) {1420			links[i].codecs = rt5682;1421			links[i].num_codecs = ARRAY_SIZE(rt5682);1422			links[i].init = acp_card_rt5682_init;1423			links[i].ops = &acp_card_rt5682_ops;1424		}1425		if (drv_data->hs_codec_id == RT5682S) {1426			links[i].codecs = rt5682s;1427			links[i].num_codecs = ARRAY_SIZE(rt5682s);1428			links[i].init = acp_card_rt5682s_init;1429			links[i].ops = &acp_card_rt5682s_ops;1430		}1431		if (drv_data->hs_codec_id == NAU8821) {1432			links[i].codecs = nau8821;1433			links[i].num_codecs = ARRAY_SIZE(nau8821);1434			links[i].init = acp_8821_init;1435			links[i].ops = &acp_8821_ops;1436		}1437		i++;1438	}1439 1440	if (drv_data->hs_cpu_id == I2S_HS) {1441		links[i].name = "acp-headset-codec";1442		links[i].id = HEADSET_BE_ID;1443		links[i].cpus = sof_hs;1444		links[i].num_cpus = ARRAY_SIZE(sof_hs);1445		links[i].platforms = sof_component;1446		links[i].num_platforms = ARRAY_SIZE(sof_component);1447		links[i].dpcm_playback = 1;1448		links[i].dpcm_capture = 1;1449		links[i].nonatomic = true;1450		links[i].no_pcm = 1;1451		if (!drv_data->hs_codec_id) {1452			/* Use dummy codec if codec id not specified */1453			links[i].codecs = &snd_soc_dummy_dlc;1454			links[i].num_codecs = 1;1455		}1456		if (drv_data->hs_codec_id == NAU8825) {1457			links[i].codecs = nau8825;1458			links[i].num_codecs = ARRAY_SIZE(nau8825);1459			links[i].init = acp_card_nau8825_init;1460			links[i].ops = &acp_card_nau8825_ops;1461		}1462		if (drv_data->hs_codec_id == RT5682S) {1463			links[i].codecs = rt5682s;1464			links[i].num_codecs = ARRAY_SIZE(rt5682s);1465			links[i].init = acp_card_rt5682s_init;1466			links[i].ops = &acp_card_rt5682s_ops;1467		}1468		i++;1469	}1470 1471	if (drv_data->amp_cpu_id == I2S_SP) {1472		links[i].name = "acp-amp-codec";1473		links[i].id = AMP_BE_ID;1474		if (drv_data->platform == RENOIR) {1475			links[i].cpus = sof_sp;1476			links[i].num_cpus = ARRAY_SIZE(sof_sp);1477		} else {1478			links[i].cpus = sof_sp_virtual;1479			links[i].num_cpus = ARRAY_SIZE(sof_sp_virtual);1480		}1481		links[i].platforms = sof_component;1482		links[i].num_platforms = ARRAY_SIZE(sof_component);1483		links[i].dpcm_playback = 1;1484		links[i].nonatomic = true;1485		links[i].no_pcm = 1;1486		if (!drv_data->amp_codec_id) {1487			/* Use dummy codec if codec id not specified */1488			links[i].codecs = &snd_soc_dummy_dlc;1489			links[i].num_codecs = 1;1490		}1491		if (drv_data->amp_codec_id == RT1019) {1492			links[i].codecs = rt1019;1493			links[i].num_codecs = ARRAY_SIZE(rt1019);1494			links[i].ops = &acp_card_rt1019_ops;1495			links[i].init = acp_card_rt1019_init;1496			card->codec_conf = rt1019_conf;1497			card->num_configs = ARRAY_SIZE(rt1019_conf);1498		}1499		if (drv_data->amp_codec_id == MAX98360A) {1500			links[i].codecs = max98360a;1501			links[i].num_codecs = ARRAY_SIZE(max98360a);1502			links[i].ops = &acp_card_maxim_ops;1503			links[i].init = acp_card_maxim_init;1504		}1505		i++;1506	}1507 1508	if (drv_data->amp_cpu_id == I2S_HS) {1509		links[i].name = "acp-amp-codec";1510		links[i].id = AMP_BE_ID;1511		links[i].cpus = sof_hs_virtual;1512		links[i].num_cpus = ARRAY_SIZE(sof_hs_virtual);1513		links[i].platforms = sof_component;1514		links[i].num_platforms = ARRAY_SIZE(sof_component);1515		links[i].dpcm_playback = 1;1516		links[i].nonatomic = true;1517		links[i].no_pcm = 1;1518		if (!drv_data->amp_codec_id) {1519			/* Use dummy codec if codec id not specified */1520			links[i].codecs = &snd_soc_dummy_dlc;1521			links[i].num_codecs = 1;1522		}1523		if (drv_data->amp_codec_id == MAX98360A) {1524			links[i].codecs = max98360a;1525			links[i].num_codecs = ARRAY_SIZE(max98360a);1526			links[i].ops = &acp_card_maxim_ops;1527			links[i].init = acp_card_maxim_init;1528		}1529		if (drv_data->amp_codec_id == MAX98388) {1530			links[i].dpcm_capture = 1;1531			links[i].codecs = max98388;1532			links[i].num_codecs = ARRAY_SIZE(max98388);1533			links[i].ops = &acp_max98388_ops;1534			links[i].init = acp_card_max98388_init;1535			card->codec_conf = max98388_conf;1536			card->num_configs = ARRAY_SIZE(max98388_conf);1537		}1538		if (drv_data->amp_codec_id == RT1019) {1539			links[i].codecs = rt1019;1540			links[i].num_codecs = ARRAY_SIZE(rt1019);1541			links[i].ops = &acp_card_rt1019_ops;1542			links[i].init = acp_card_rt1019_init;1543			card->codec_conf = rt1019_conf;1544			card->num_configs = ARRAY_SIZE(rt1019_conf);1545		}1546		i++;1547	}1548 1549	if (drv_data->bt_cpu_id == I2S_BT) {1550		links[i].name = "acp-bt-codec";1551		links[i].id = BT_BE_ID;1552		links[i].cpus = sof_bt;1553		links[i].num_cpus = ARRAY_SIZE(sof_bt);1554		links[i].platforms = sof_component;1555		links[i].num_platforms = ARRAY_SIZE(sof_component);1556		links[i].dpcm_playback = 1;1557		links[i].dpcm_capture = 1;1558		links[i].nonatomic = true;1559		links[i].no_pcm = 1;1560		if (!drv_data->bt_codec_id) {1561			/* Use dummy codec if codec id not specified */1562			links[i].codecs = &snd_soc_dummy_dlc;1563			links[i].num_codecs = 1;1564		}1565		i++;1566	}1567 1568	if (drv_data->dmic_cpu_id == DMIC) {1569		links[i].name = "acp-dmic-codec";1570		links[i].id = DMIC_BE_ID;1571		links[i].codecs = dmic_codec;1572		links[i].num_codecs = ARRAY_SIZE(dmic_codec);1573		links[i].cpus = sof_dmic;1574		links[i].num_cpus = ARRAY_SIZE(sof_dmic);1575		links[i].platforms = sof_component;1576		links[i].num_platforms = ARRAY_SIZE(sof_component);1577		links[i].dpcm_capture = 1;1578		links[i].nonatomic = true;1579		links[i].no_pcm = 1;1580	}1581 1582	card->dai_link = links;1583	card->num_links = num_links;1584	card->set_bias_level = acp_rtk_set_bias_level;1585 1586	return 0;1587}1588EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, SND_SOC_AMD_MACH);1589 1590int acp_legacy_dai_links_create(struct snd_soc_card *card)1591{1592	struct snd_soc_dai_link *links;1593	struct device *dev = card->dev;1594	struct acp_card_drvdata *drv_data = card->drvdata;1595	int i = 0, num_links = 0;1596	int rc;1597 1598	if (drv_data->hs_cpu_id)1599		num_links++;1600	if (drv_data->amp_cpu_id)1601		num_links++;1602	if (drv_data->dmic_cpu_id)1603		num_links++;1604 1605	links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);1606	if (!links)1607		return -ENOMEM;1608 1609	if (drv_data->hs_cpu_id == I2S_SP) {1610		links[i].name = "acp-headset-codec";1611		links[i].id = HEADSET_BE_ID;1612		links[i].cpus = i2s_sp;1613		links[i].num_cpus = ARRAY_SIZE(i2s_sp);1614		links[i].platforms = platform_component;1615		links[i].num_platforms = ARRAY_SIZE(platform_component);1616		links[i].dpcm_playback = 1;1617		links[i].dpcm_capture = 1;1618		if (!drv_data->hs_codec_id) {1619			/* Use dummy codec if codec id not specified */1620			links[i].codecs = &snd_soc_dummy_dlc;1621			links[i].num_codecs = 1;1622		}1623		if (drv_data->hs_codec_id == RT5682) {1624			links[i].codecs = rt5682;1625			links[i].num_codecs = ARRAY_SIZE(rt5682);1626			links[i].init = acp_card_rt5682_init;1627			links[i].ops = &acp_card_rt5682_ops;1628		}1629		if (drv_data->hs_codec_id == RT5682S) {1630			links[i].codecs = rt5682s;1631			links[i].num_codecs = ARRAY_SIZE(rt5682s);1632			links[i].init = acp_card_rt5682s_init;1633			links[i].ops = &acp_card_rt5682s_ops;1634		}1635		if (drv_data->hs_codec_id == ES83XX) {1636			rc = acp_ops_configure_link(card, &links[i]);1637			if (rc != 0) {1638				dev_err(dev, "Failed to configure link for ES83XX: %d\n", rc);1639				return rc;1640			}1641		}1642		i++;1643	}1644 1645	if (drv_data->hs_cpu_id == I2S_HS) {1646		links[i].name = "acp-headset-codec";1647		links[i].id = HEADSET_BE_ID;1648		links[i].cpus = i2s_hs;1649		links[i].num_cpus = ARRAY_SIZE(i2s_hs);1650		if (drv_data->platform == REMBRANDT) {1651			links[i].platforms = platform_rmb_component;1652			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);1653		} else if (drv_data->platform == ACP63) {1654			links[i].platforms = platform_acp63_component;1655			links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);1656		} else {1657			links[i].platforms = platform_component;1658			links[i].num_platforms = ARRAY_SIZE(platform_component);1659		}1660		links[i].dpcm_playback = 1;1661		links[i].dpcm_capture = 1;1662		if (!drv_data->hs_codec_id) {1663			/* Use dummy codec if codec id not specified */1664			links[i].codecs = &snd_soc_dummy_dlc;1665			links[i].num_codecs = 1;1666		}1667		if (drv_data->hs_codec_id == NAU8825) {1668			links[i].codecs = nau8825;1669			links[i].num_codecs = ARRAY_SIZE(nau8825);1670			links[i].init = acp_card_nau8825_init;1671			links[i].ops = &acp_card_nau8825_ops;1672		}1673		if (drv_data->hs_codec_id == RT5682S) {1674			links[i].codecs = rt5682s;1675			links[i].num_codecs = ARRAY_SIZE(rt5682s);1676			links[i].init = acp_card_rt5682s_init;1677			links[i].ops = &acp_card_rt5682s_ops;1678		}1679		i++;1680	}1681 1682	if (drv_data->amp_cpu_id == I2S_SP) {1683		links[i].name = "acp-amp-codec";1684		links[i].id = AMP_BE_ID;1685		links[i].cpus = i2s_sp;1686		links[i].num_cpus = ARRAY_SIZE(i2s_sp);1687		links[i].platforms = platform_component;1688		links[i].num_platforms = ARRAY_SIZE(platform_component);1689		links[i].dpcm_playback = 1;1690		if (!drv_data->amp_codec_id) {1691			/* Use dummy codec if codec id not specified */1692			links[i].codecs = &snd_soc_dummy_dlc;1693			links[i].num_codecs = 1;1694		}1695		if (drv_data->amp_codec_id == RT1019) {1696			links[i].codecs = rt1019;1697			links[i].num_codecs = ARRAY_SIZE(rt1019);1698			links[i].ops = &acp_card_rt1019_ops;1699			links[i].init = acp_card_rt1019_init;1700			card->codec_conf = rt1019_conf;1701			card->num_configs = ARRAY_SIZE(rt1019_conf);1702		}1703		if (drv_data->amp_codec_id == MAX98360A) {1704			links[i].codecs = max98360a;1705			links[i].num_codecs = ARRAY_SIZE(max98360a);1706			links[i].ops = &acp_card_maxim_ops;1707			links[i].init = acp_card_maxim_init;1708		}1709		i++;1710	}1711 1712	if (drv_data->amp_cpu_id == I2S_HS) {1713		links[i].name = "acp-amp-codec";1714		links[i].id = AMP_BE_ID;1715		links[i].cpus = i2s_hs;1716		links[i].num_cpus = ARRAY_SIZE(i2s_hs);1717		if (drv_data->platform == REMBRANDT) {1718			links[i].platforms = platform_rmb_component;1719			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);1720		} else if (drv_data->platform == ACP63) {1721			links[i].platforms = platform_acp63_component;1722			links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);1723		} else {1724			links[i].platforms = platform_component;1725			links[i].num_platforms = ARRAY_SIZE(platform_component);1726		}1727		links[i].dpcm_playback = 1;1728		if (!drv_data->amp_codec_id) {1729			/* Use dummy codec if codec id not specified */1730			links[i].codecs = &snd_soc_dummy_dlc;1731			links[i].num_codecs = 1;1732		}1733		if (drv_data->amp_codec_id == MAX98360A) {1734			links[i].codecs = max98360a;1735			links[i].num_codecs = ARRAY_SIZE(max98360a);1736			links[i].ops = &acp_card_maxim_ops;1737			links[i].init = acp_card_maxim_init;1738		}1739		if (drv_data->amp_codec_id == RT1019) {1740			links[i].codecs = rt1019;1741			links[i].num_codecs = ARRAY_SIZE(rt1019);1742			links[i].ops = &acp_card_rt1019_ops;1743			links[i].init = acp_card_rt1019_init;1744			card->codec_conf = rt1019_conf;1745			card->num_configs = ARRAY_SIZE(rt1019_conf);1746		}1747		i++;1748	}1749 1750	if (drv_data->dmic_cpu_id == DMIC) {1751		links[i].name = "acp-dmic-codec";1752		links[i].id = DMIC_BE_ID;1753		if (drv_data->dmic_codec_id == DMIC) {1754			links[i].codecs = dmic_codec;1755			links[i].num_codecs = ARRAY_SIZE(dmic_codec);1756		} else {1757			/* Use dummy codec if codec id not specified */1758			links[i].codecs = &snd_soc_dummy_dlc;1759			links[i].num_codecs = 1;1760		}1761		links[i].cpus = pdm_dmic;1762		links[i].num_cpus = ARRAY_SIZE(pdm_dmic);1763		if (drv_data->platform == REMBRANDT) {1764			links[i].platforms = platform_rmb_component;1765			links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);1766		} else if (drv_data->platform == ACP63) {1767			links[i].platforms = platform_acp63_component;1768			links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);1769		} else if ((drv_data->platform == ACP70) || (drv_data->platform == ACP71)) {1770			links[i].platforms = platform_acp70_component;1771			links[i].num_platforms = ARRAY_SIZE(platform_acp70_component);1772		} else {1773			links[i].platforms = platform_component;1774			links[i].num_platforms = ARRAY_SIZE(platform_component);1775		}1776		links[i].ops = &acp_card_dmic_ops;1777		links[i].dpcm_capture = 1;1778	}1779 1780	card->dai_link = links;1781	card->num_links = num_links;1782	card->set_bias_level = acp_rtk_set_bias_level;1783 1784	return 0;1785}1786EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, SND_SOC_AMD_MACH);1787 1788MODULE_DESCRIPTION("AMD ACP Common Machine driver");1789MODULE_LICENSE("GPL v2");1790