812 lines · c
1// SPDX-License-Identifier: MIT2//3// Machine driver for AMD ACP Audio engine using DA7219, RT5682 & MAX98357 codec4//5//Copyright 2017-2021 Advanced Micro Devices, Inc.6 7#include <sound/core.h>8#include <sound/soc.h>9#include <sound/pcm.h>10#include <sound/pcm_params.h>11#include <sound/soc-dapm.h>12#include <sound/jack.h>13#include <linux/clk.h>14#include <linux/gpio.h>15#include <linux/module.h>16#include <linux/regulator/machine.h>17#include <linux/regulator/driver.h>18#include <linux/i2c.h>19#include <linux/input.h>20#include <linux/acpi.h>21 22#include "acp.h"23#include "../codecs/da7219.h"24#include "../codecs/rt5682.h"25 26#define CZ_PLAT_CLK 4800000027#define DUAL_CHANNEL 228#define RT5682_PLL_FREQ (48000 * 512)29 30static struct snd_soc_jack cz_jack;31static struct snd_soc_jack_pin cz_jack_pins[] = {32 {33 .pin = "Headphone Jack",34 .mask = SND_JACK_HEADPHONE,35 },36 {37 .pin = "Headset Mic",38 .mask = SND_JACK_MICROPHONE,39 },40 {41 .pin = "Line Out",42 .mask = SND_JACK_LINEOUT,43 },44};45 46static struct clk *da7219_dai_wclk;47static struct clk *da7219_dai_bclk;48static struct clk *rt5682_dai_wclk;49static struct clk *rt5682_dai_bclk;50 51void *acp_soc_is_rltk_max(struct device *dev);52 53static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)54{55 int ret;56 struct snd_soc_card *card = rtd->card;57 struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);58 struct snd_soc_component *component = codec_dai->component;59 60 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);61 62 ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK,63 CZ_PLAT_CLK, SND_SOC_CLOCK_IN);64 if (ret < 0) {65 dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);66 return ret;67 }68 69 ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL,70 CZ_PLAT_CLK, DA7219_PLL_FREQ_OUT_98304);71 if (ret < 0) {72 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);73 return ret;74 }75 76 da7219_dai_wclk = devm_clk_get(component->dev, "da7219-dai-wclk");77 if (IS_ERR(da7219_dai_wclk))78 return PTR_ERR(da7219_dai_wclk);79 80 da7219_dai_bclk = devm_clk_get(component->dev, "da7219-dai-bclk");81 if (IS_ERR(da7219_dai_bclk))82 return PTR_ERR(da7219_dai_bclk);83 84 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",85 SND_JACK_HEADSET | SND_JACK_LINEOUT |86 SND_JACK_BTN_0 | SND_JACK_BTN_1 |87 SND_JACK_BTN_2 | SND_JACK_BTN_3,88 &cz_jack,89 cz_jack_pins,90 ARRAY_SIZE(cz_jack_pins));91 if (ret) {92 dev_err(card->dev, "HP jack creation failed %d\n", ret);93 return ret;94 }95 96 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);97 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);98 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);99 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);100 101 snd_soc_component_set_jack(component, &cz_jack, NULL);102 103 return 0;104}105 106static int da7219_clk_enable(struct snd_pcm_substream *substream)107{108 int ret = 0;109 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);110 111 /*112 * Set wclk to 48000 because the rate constraint of this driver is113 * 48000. ADAU7002 spec: "The ADAU7002 requires a BCLK rate that is114 * minimum of 64x the LRCLK sample rate." DA7219 is the only clk115 * source so for all codecs we have to limit bclk to 64X lrclk.116 */117 clk_set_rate(da7219_dai_wclk, 48000);118 clk_set_rate(da7219_dai_bclk, 48000 * 64);119 ret = clk_prepare_enable(da7219_dai_bclk);120 if (ret < 0) {121 dev_err(rtd->dev, "can't enable master clock %d\n", ret);122 return ret;123 }124 125 return ret;126}127 128static void da7219_clk_disable(void)129{130 clk_disable_unprepare(da7219_dai_bclk);131}132 133static int cz_rt5682_init(struct snd_soc_pcm_runtime *rtd)134{135 int ret;136 struct snd_soc_card *card = rtd->card;137 struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);138 struct snd_soc_component *component = codec_dai->component;139 140 dev_info(codec_dai->dev, "codec dai name = %s\n", codec_dai->name);141 142 /* Set codec sysclk */143 ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,144 RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);145 if (ret < 0) {146 dev_err(codec_dai->dev,147 "Failed to set rt5682 SYSCLK: %d\n", ret);148 return ret;149 }150 /* set codec PLL */151 ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,152 CZ_PLAT_CLK, RT5682_PLL_FREQ);153 if (ret < 0) {154 dev_err(codec_dai->dev, "can't set rt5682 PLL: %d\n", ret);155 return ret;156 }157 158 rt5682_dai_wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");159 if (IS_ERR(rt5682_dai_wclk))160 return PTR_ERR(rt5682_dai_wclk);161 162 rt5682_dai_bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");163 if (IS_ERR(rt5682_dai_bclk))164 return PTR_ERR(rt5682_dai_bclk);165 166 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",167 SND_JACK_HEADSET | SND_JACK_LINEOUT |168 SND_JACK_BTN_0 | SND_JACK_BTN_1 |169 SND_JACK_BTN_2 | SND_JACK_BTN_3,170 &cz_jack,171 cz_jack_pins,172 ARRAY_SIZE(cz_jack_pins));173 if (ret) {174 dev_err(card->dev, "HP jack creation failed %d\n", ret);175 return ret;176 }177 178 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);179 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);180 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);181 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);182 183 ret = snd_soc_component_set_jack(component, &cz_jack, NULL);184 if (ret) {185 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);186 return ret;187 }188 return 0;189}190 191static int rt5682_clk_enable(struct snd_pcm_substream *substream)192{193 int ret;194 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);195 196 /*197 * Set wclk to 48000 because the rate constraint of this driver is198 * 48000. ADAU7002 spec: "The ADAU7002 requires a BCLK rate that is199 * minimum of 64x the LRCLK sample rate." RT5682 is the only clk200 * source so for all codecs we have to limit bclk to 64X lrclk.201 */202 ret = clk_set_rate(rt5682_dai_wclk, 48000);203 if (ret) {204 dev_err(rtd->dev, "Error setting wclk rate: %d\n", ret);205 return ret;206 }207 ret = clk_set_rate(rt5682_dai_bclk, 48000 * 64);208 if (ret) {209 dev_err(rtd->dev, "Error setting bclk rate: %d\n", ret);210 return ret;211 }212 ret = clk_prepare_enable(rt5682_dai_wclk);213 if (ret < 0) {214 dev_err(rtd->dev, "can't enable wclk %d\n", ret);215 return ret;216 }217 return ret;218}219 220static void rt5682_clk_disable(void)221{222 clk_disable_unprepare(rt5682_dai_wclk);223}224 225static const unsigned int channels[] = {226 DUAL_CHANNEL,227};228 229static const unsigned int rates[] = {230 48000,231};232 233static const struct snd_pcm_hw_constraint_list constraints_rates = {234 .count = ARRAY_SIZE(rates),235 .list = rates,236 .mask = 0,237};238 239static const struct snd_pcm_hw_constraint_list constraints_channels = {240 .count = ARRAY_SIZE(channels),241 .list = channels,242 .mask = 0,243};244 245static int cz_da7219_play_startup(struct snd_pcm_substream *substream)246{247 struct snd_pcm_runtime *runtime = substream->runtime;248 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);249 struct snd_soc_card *card = rtd->card;250 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);251 252 /*253 * On this platform for PCM device we support stereo254 */255 256 runtime->hw.channels_max = DUAL_CHANNEL;257 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,258 &constraints_channels);259 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,260 &constraints_rates);261 262 machine->play_i2s_instance = I2S_SP_INSTANCE;263 return da7219_clk_enable(substream);264}265 266static int cz_da7219_cap_startup(struct snd_pcm_substream *substream)267{268 struct snd_pcm_runtime *runtime = substream->runtime;269 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);270 struct snd_soc_card *card = rtd->card;271 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);272 273 /*274 * On this platform for PCM device we support stereo275 */276 277 runtime->hw.channels_max = DUAL_CHANNEL;278 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,279 &constraints_channels);280 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,281 &constraints_rates);282 283 machine->cap_i2s_instance = I2S_SP_INSTANCE;284 machine->capture_channel = CAP_CHANNEL1;285 return da7219_clk_enable(substream);286}287 288static int cz_max_startup(struct snd_pcm_substream *substream)289{290 struct snd_pcm_runtime *runtime = substream->runtime;291 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);292 struct snd_soc_card *card = rtd->card;293 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);294 295 /*296 * On this platform for PCM device we support stereo297 */298 299 runtime->hw.channels_max = DUAL_CHANNEL;300 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,301 &constraints_channels);302 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,303 &constraints_rates);304 305 machine->play_i2s_instance = I2S_BT_INSTANCE;306 return da7219_clk_enable(substream);307}308 309static int cz_dmic0_startup(struct snd_pcm_substream *substream)310{311 struct snd_pcm_runtime *runtime = substream->runtime;312 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);313 struct snd_soc_card *card = rtd->card;314 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);315 316 /*317 * On this platform for PCM device we support stereo318 */319 320 runtime->hw.channels_max = DUAL_CHANNEL;321 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,322 &constraints_channels);323 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,324 &constraints_rates);325 326 machine->cap_i2s_instance = I2S_BT_INSTANCE;327 return da7219_clk_enable(substream);328}329 330static int cz_dmic1_startup(struct snd_pcm_substream *substream)331{332 struct snd_pcm_runtime *runtime = substream->runtime;333 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);334 struct snd_soc_card *card = rtd->card;335 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);336 337 /*338 * On this platform for PCM device we support stereo339 */340 341 runtime->hw.channels_max = DUAL_CHANNEL;342 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,343 &constraints_channels);344 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,345 &constraints_rates);346 347 machine->cap_i2s_instance = I2S_SP_INSTANCE;348 machine->capture_channel = CAP_CHANNEL0;349 return da7219_clk_enable(substream);350}351 352static void cz_da7219_shutdown(struct snd_pcm_substream *substream)353{354 da7219_clk_disable();355}356 357static int cz_rt5682_play_startup(struct snd_pcm_substream *substream)358{359 struct snd_pcm_runtime *runtime = substream->runtime;360 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);361 struct snd_soc_card *card = rtd->card;362 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);363 364 /*365 * On this platform for PCM device we support stereo366 */367 368 runtime->hw.channels_max = DUAL_CHANNEL;369 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,370 &constraints_channels);371 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,372 &constraints_rates);373 374 machine->play_i2s_instance = I2S_SP_INSTANCE;375 return rt5682_clk_enable(substream);376}377 378static int cz_rt5682_cap_startup(struct snd_pcm_substream *substream)379{380 struct snd_pcm_runtime *runtime = substream->runtime;381 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);382 struct snd_soc_card *card = rtd->card;383 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);384 385 /*386 * On this platform for PCM device we support stereo387 */388 389 runtime->hw.channels_max = DUAL_CHANNEL;390 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,391 &constraints_channels);392 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,393 &constraints_rates);394 395 machine->cap_i2s_instance = I2S_SP_INSTANCE;396 machine->capture_channel = CAP_CHANNEL1;397 return rt5682_clk_enable(substream);398}399 400static int cz_rt5682_max_startup(struct snd_pcm_substream *substream)401{402 struct snd_pcm_runtime *runtime = substream->runtime;403 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);404 struct snd_soc_card *card = rtd->card;405 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);406 407 /*408 * On this platform for PCM device we support stereo409 */410 411 runtime->hw.channels_max = DUAL_CHANNEL;412 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,413 &constraints_channels);414 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,415 &constraints_rates);416 417 machine->play_i2s_instance = I2S_BT_INSTANCE;418 return rt5682_clk_enable(substream);419}420 421static int cz_rt5682_dmic0_startup(struct snd_pcm_substream *substream)422{423 struct snd_pcm_runtime *runtime = substream->runtime;424 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);425 struct snd_soc_card *card = rtd->card;426 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);427 428 /*429 * On this platform for PCM device we support stereo430 */431 432 runtime->hw.channels_max = DUAL_CHANNEL;433 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,434 &constraints_channels);435 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,436 &constraints_rates);437 438 machine->cap_i2s_instance = I2S_BT_INSTANCE;439 return rt5682_clk_enable(substream);440}441 442static int cz_rt5682_dmic1_startup(struct snd_pcm_substream *substream)443{444 struct snd_pcm_runtime *runtime = substream->runtime;445 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);446 struct snd_soc_card *card = rtd->card;447 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);448 449 /*450 * On this platform for PCM device we support stereo451 */452 453 runtime->hw.channels_max = DUAL_CHANNEL;454 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,455 &constraints_channels);456 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,457 &constraints_rates);458 459 machine->cap_i2s_instance = I2S_SP_INSTANCE;460 machine->capture_channel = CAP_CHANNEL0;461 return rt5682_clk_enable(substream);462}463 464static void cz_rt5682_shutdown(struct snd_pcm_substream *substream)465{466 rt5682_clk_disable();467}468 469static const struct snd_soc_ops cz_da7219_play_ops = {470 .startup = cz_da7219_play_startup,471 .shutdown = cz_da7219_shutdown,472};473 474static const struct snd_soc_ops cz_da7219_cap_ops = {475 .startup = cz_da7219_cap_startup,476 .shutdown = cz_da7219_shutdown,477};478 479static const struct snd_soc_ops cz_max_play_ops = {480 .startup = cz_max_startup,481 .shutdown = cz_da7219_shutdown,482};483 484static const struct snd_soc_ops cz_dmic0_cap_ops = {485 .startup = cz_dmic0_startup,486 .shutdown = cz_da7219_shutdown,487};488 489static const struct snd_soc_ops cz_dmic1_cap_ops = {490 .startup = cz_dmic1_startup,491 .shutdown = cz_da7219_shutdown,492};493 494static const struct snd_soc_ops cz_rt5682_play_ops = {495 .startup = cz_rt5682_play_startup,496 .shutdown = cz_rt5682_shutdown,497};498 499static const struct snd_soc_ops cz_rt5682_cap_ops = {500 .startup = cz_rt5682_cap_startup,501 .shutdown = cz_rt5682_shutdown,502};503 504static const struct snd_soc_ops cz_rt5682_max_play_ops = {505 .startup = cz_rt5682_max_startup,506 .shutdown = cz_rt5682_shutdown,507};508 509static const struct snd_soc_ops cz_rt5682_dmic0_cap_ops = {510 .startup = cz_rt5682_dmic0_startup,511 .shutdown = cz_rt5682_shutdown,512};513 514static const struct snd_soc_ops cz_rt5682_dmic1_cap_ops = {515 .startup = cz_rt5682_dmic1_startup,516 .shutdown = cz_rt5682_shutdown,517};518 519SND_SOC_DAILINK_DEF(designware1,520 DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.1.auto")));521SND_SOC_DAILINK_DEF(designware2,522 DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto")));523SND_SOC_DAILINK_DEF(designware3,524 DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.3.auto")));525 526SND_SOC_DAILINK_DEF(dlgs,527 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", "da7219-hifi")));528SND_SOC_DAILINK_DEF(rt5682,529 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));530SND_SOC_DAILINK_DEF(mx,531 DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", "HiFi")));532SND_SOC_DAILINK_DEF(adau,533 DAILINK_COMP_ARRAY(COMP_CODEC("ADAU7002:00", "adau7002-hifi")));534 535SND_SOC_DAILINK_DEF(platform,536 DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.0.auto")));537 538static struct snd_soc_dai_link cz_dai_7219_98357[] = {539 {540 .name = "amd-da7219-play",541 .stream_name = "Playback",542 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF543 | SND_SOC_DAIFMT_CBP_CFP,544 .init = cz_da7219_init,545 .dpcm_playback = 1,546 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,547 .ops = &cz_da7219_play_ops,548 SND_SOC_DAILINK_REG(designware1, dlgs, platform),549 },550 {551 .name = "amd-da7219-cap",552 .stream_name = "Capture",553 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF554 | SND_SOC_DAIFMT_CBP_CFP,555 .dpcm_capture = 1,556 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,557 .ops = &cz_da7219_cap_ops,558 SND_SOC_DAILINK_REG(designware2, dlgs, platform),559 },560 {561 .name = "amd-max98357-play",562 .stream_name = "HiFi Playback",563 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF564 | SND_SOC_DAIFMT_CBP_CFP,565 .dpcm_playback = 1,566 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,567 .ops = &cz_max_play_ops,568 SND_SOC_DAILINK_REG(designware3, mx, platform),569 },570 {571 /* C panel DMIC */572 .name = "dmic0",573 .stream_name = "DMIC0 Capture",574 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF575 | SND_SOC_DAIFMT_CBP_CFP,576 .dpcm_capture = 1,577 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,578 .ops = &cz_dmic0_cap_ops,579 SND_SOC_DAILINK_REG(designware3, adau, platform),580 },581 {582 /* A/B panel DMIC */583 .name = "dmic1",584 .stream_name = "DMIC1 Capture",585 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF586 | SND_SOC_DAIFMT_CBP_CFP,587 .dpcm_capture = 1,588 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,589 .ops = &cz_dmic1_cap_ops,590 SND_SOC_DAILINK_REG(designware2, adau, platform),591 },592};593 594static struct snd_soc_dai_link cz_dai_5682_98357[] = {595 {596 .name = "amd-rt5682-play",597 .stream_name = "Playback",598 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF599 | SND_SOC_DAIFMT_CBP_CFP,600 .init = cz_rt5682_init,601 .dpcm_playback = 1,602 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,603 .ops = &cz_rt5682_play_ops,604 SND_SOC_DAILINK_REG(designware1, rt5682, platform),605 },606 {607 .name = "amd-rt5682-cap",608 .stream_name = "Capture",609 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF610 | SND_SOC_DAIFMT_CBP_CFP,611 .dpcm_capture = 1,612 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,613 .ops = &cz_rt5682_cap_ops,614 SND_SOC_DAILINK_REG(designware2, rt5682, platform),615 },616 {617 .name = "amd-max98357-play",618 .stream_name = "HiFi Playback",619 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF620 | SND_SOC_DAIFMT_CBP_CFP,621 .dpcm_playback = 1,622 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,623 .ops = &cz_rt5682_max_play_ops,624 SND_SOC_DAILINK_REG(designware3, mx, platform),625 },626 {627 /* C panel DMIC */628 .name = "dmic0",629 .stream_name = "DMIC0 Capture",630 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF631 | SND_SOC_DAIFMT_CBP_CFP,632 .dpcm_capture = 1,633 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,634 .ops = &cz_rt5682_dmic0_cap_ops,635 SND_SOC_DAILINK_REG(designware3, adau, platform),636 },637 {638 /* A/B panel DMIC */639 .name = "dmic1",640 .stream_name = "DMIC1 Capture",641 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF642 | SND_SOC_DAIFMT_CBP_CFP,643 .dpcm_capture = 1,644 .trigger_stop = SND_SOC_TRIGGER_ORDER_LDC,645 .ops = &cz_rt5682_dmic1_cap_ops,646 SND_SOC_DAILINK_REG(designware2, adau, platform),647 },648};649 650static const struct snd_soc_dapm_widget cz_widgets[] = {651 SND_SOC_DAPM_HP("Headphones", NULL),652 SND_SOC_DAPM_SPK("Speakers", NULL),653 SND_SOC_DAPM_LINE("Line Out", NULL),654 SND_SOC_DAPM_MIC("Headset Mic", NULL),655 SND_SOC_DAPM_MIC("Int Mic", NULL),656};657 658static const struct snd_soc_dapm_route cz_audio_route[] = {659 {"Headphones", NULL, "HPL"},660 {"Headphones", NULL, "HPR"},661 {"MIC", NULL, "Headset Mic"},662 {"Speakers", NULL, "Speaker"},663 {"PDM_DAT", NULL, "Int Mic"},664};665 666static const struct snd_soc_dapm_route cz_rt5682_audio_route[] = {667 {"Headphones", NULL, "HPOL"},668 {"Headphones", NULL, "HPOR"},669 {"IN1P", NULL, "Headset Mic"},670 {"Speakers", NULL, "Speaker"},671 {"PDM_DAT", NULL, "Int Mic"},672};673 674static const struct snd_kcontrol_new cz_mc_controls[] = {675 SOC_DAPM_PIN_SWITCH("Headphones"),676 SOC_DAPM_PIN_SWITCH("Speakers"),677 SOC_DAPM_PIN_SWITCH("Line Out"),678 SOC_DAPM_PIN_SWITCH("Headset Mic"),679 SOC_DAPM_PIN_SWITCH("Int Mic"),680};681 682static struct snd_soc_card cz_card = {683 .name = "acpd7219m98357",684 .owner = THIS_MODULE,685 .dai_link = cz_dai_7219_98357,686 .num_links = ARRAY_SIZE(cz_dai_7219_98357),687 .dapm_widgets = cz_widgets,688 .num_dapm_widgets = ARRAY_SIZE(cz_widgets),689 .dapm_routes = cz_audio_route,690 .num_dapm_routes = ARRAY_SIZE(cz_audio_route),691 .controls = cz_mc_controls,692 .num_controls = ARRAY_SIZE(cz_mc_controls),693};694 695static struct snd_soc_card cz_rt5682_card = {696 .name = "acpr5682m98357",697 .owner = THIS_MODULE,698 .dai_link = cz_dai_5682_98357,699 .num_links = ARRAY_SIZE(cz_dai_5682_98357),700 .dapm_widgets = cz_widgets,701 .num_dapm_widgets = ARRAY_SIZE(cz_widgets),702 .dapm_routes = cz_rt5682_audio_route,703 .controls = cz_mc_controls,704 .num_controls = ARRAY_SIZE(cz_mc_controls),705};706 707void *acp_soc_is_rltk_max(struct device *dev)708{709 const struct acpi_device_id *match;710 711 match = acpi_match_device(dev->driver->acpi_match_table, dev);712 if (!match)713 return NULL;714 return (void *)match->driver_data;715}716 717static struct regulator_consumer_supply acp_da7219_supplies[] = {718 REGULATOR_SUPPLY("VDD", "i2c-DLGS7219:00"),719 REGULATOR_SUPPLY("VDDMIC", "i2c-DLGS7219:00"),720 REGULATOR_SUPPLY("VDDIO", "i2c-DLGS7219:00"),721 REGULATOR_SUPPLY("IOVDD", "ADAU7002:00"),722};723 724static struct regulator_init_data acp_da7219_data = {725 .constraints = {726 .always_on = 1,727 },728 .num_consumer_supplies = ARRAY_SIZE(acp_da7219_supplies),729 .consumer_supplies = acp_da7219_supplies,730};731 732static struct regulator_config acp_da7219_cfg = {733 .init_data = &acp_da7219_data,734};735 736static const struct regulator_ops acp_da7219_ops = {737};738 739static const struct regulator_desc acp_da7219_desc = {740 .name = "reg-fixed-1.8V",741 .type = REGULATOR_VOLTAGE,742 .owner = THIS_MODULE,743 .ops = &acp_da7219_ops,744 .fixed_uV = 1800000, /* 1.8V */745 .n_voltages = 1,746};747 748static int cz_probe(struct platform_device *pdev)749{750 int ret;751 struct snd_soc_card *card;752 struct acp_platform_info *machine;753 struct regulator_dev *rdev;754 struct device *dev = &pdev->dev;755 756 card = (struct snd_soc_card *)acp_soc_is_rltk_max(dev);757 if (!card)758 return -ENODEV;759 if (!strcmp(card->name, "acpd7219m98357")) {760 acp_da7219_cfg.dev = &pdev->dev;761 rdev = devm_regulator_register(&pdev->dev, &acp_da7219_desc,762 &acp_da7219_cfg);763 if (IS_ERR(rdev)) {764 dev_err(&pdev->dev, "Failed to register regulator: %d\n",765 (int)PTR_ERR(rdev));766 return -EINVAL;767 }768 }769 770 machine = devm_kzalloc(&pdev->dev, sizeof(struct acp_platform_info),771 GFP_KERNEL);772 if (!machine)773 return -ENOMEM;774 card->dev = &pdev->dev;775 platform_set_drvdata(pdev, card);776 snd_soc_card_set_drvdata(card, machine);777 ret = devm_snd_soc_register_card(&pdev->dev, card);778 if (ret) {779 return dev_err_probe(&pdev->dev, ret,780 "devm_snd_soc_register_card(%s) failed\n",781 card->name);782 }783 acp_bt_uart_enable = !device_property_read_bool(&pdev->dev,784 "bt-pad-enable");785 return 0;786}787 788#ifdef CONFIG_ACPI789static const struct acpi_device_id cz_audio_acpi_match[] = {790 { "AMD7219", (unsigned long)&cz_card },791 { "AMDI5682", (unsigned long)&cz_rt5682_card},792 {},793};794MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match);795#endif796 797static struct platform_driver cz_pcm_driver = {798 .driver = {799 .name = "cz-da7219-max98357a",800 .acpi_match_table = ACPI_PTR(cz_audio_acpi_match),801 .pm = &snd_soc_pm_ops,802 },803 .probe = cz_probe,804};805 806module_platform_driver(cz_pcm_driver);807 808MODULE_AUTHOR("akshu.agrawal@amd.com");809MODULE_AUTHOR("Vijendar.Mukunda@amd.com");810MODULE_DESCRIPTION("DA7219, RT5682 & MAX98357A audio support");811MODULE_LICENSE("GPL v2");812