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