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;
  36extern bool bt_uart_enable;
  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_CBM_CFM,
 526                .init = cz_da7219_init,
 527                .dpcm_playback = 1,
 528                .ops = &cz_da7219_play_ops,
 529                SND_SOC_DAILINK_REG(designware1, dlgs, platform),
 530        },
 531        {
 532                .name = "amd-da7219-cap",
 533                .stream_name = "Capture",
 534                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 535                                | SND_SOC_DAIFMT_CBM_CFM,
 536                .dpcm_capture = 1,
 537                .ops = &cz_da7219_cap_ops,
 538                SND_SOC_DAILINK_REG(designware2, dlgs, platform),
 539        },
 540        {
 541                .name = "amd-max98357-play",
 542                .stream_name = "HiFi Playback",
 543                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 544                                | SND_SOC_DAIFMT_CBM_CFM,
 545                .dpcm_playback = 1,
 546                .ops = &cz_max_play_ops,
 547                SND_SOC_DAILINK_REG(designware3, mx, platform),
 548        },
 549        {
 550                /* C panel DMIC */
 551                .name = "dmic0",
 552                .stream_name = "DMIC0 Capture",
 553                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 554                                | SND_SOC_DAIFMT_CBM_CFM,
 555                .dpcm_capture = 1,
 556                .ops = &cz_dmic0_cap_ops,
 557                SND_SOC_DAILINK_REG(designware3, adau, platform),
 558        },
 559        {
 560                /* A/B panel DMIC */
 561                .name = "dmic1",
 562                .stream_name = "DMIC1 Capture",
 563                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 564                                | SND_SOC_DAIFMT_CBM_CFM,
 565                .dpcm_capture = 1,
 566                .ops = &cz_dmic1_cap_ops,
 567                SND_SOC_DAILINK_REG(designware2, adau, platform),
 568        },
 569};
 570
 571static struct snd_soc_dai_link cz_dai_5682_98357[] = {
 572        {
 573                .name = "amd-rt5682-play",
 574                .stream_name = "Playback",
 575                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 576                                | SND_SOC_DAIFMT_CBM_CFM,
 577                .init = cz_rt5682_init,
 578                .dpcm_playback = 1,
 579                .ops = &cz_rt5682_play_ops,
 580                SND_SOC_DAILINK_REG(designware1, rt5682, platform),
 581        },
 582        {
 583                .name = "amd-rt5682-cap",
 584                .stream_name = "Capture",
 585                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 586                                | SND_SOC_DAIFMT_CBM_CFM,
 587                .dpcm_capture = 1,
 588                .ops = &cz_rt5682_cap_ops,
 589                SND_SOC_DAILINK_REG(designware2, rt5682, platform),
 590        },
 591        {
 592                .name = "amd-max98357-play",
 593                .stream_name = "HiFi Playback",
 594                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 595                                | SND_SOC_DAIFMT_CBM_CFM,
 596                .dpcm_playback = 1,
 597                .ops = &cz_rt5682_max_play_ops,
 598                SND_SOC_DAILINK_REG(designware3, mx, platform),
 599        },
 600        {
 601                /* C panel DMIC */
 602                .name = "dmic0",
 603                .stream_name = "DMIC0 Capture",
 604                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 605                                | SND_SOC_DAIFMT_CBM_CFM,
 606                .dpcm_capture = 1,
 607                .ops = &cz_rt5682_dmic0_cap_ops,
 608                SND_SOC_DAILINK_REG(designware3, adau, platform),
 609        },
 610        {
 611                /* A/B panel DMIC */
 612                .name = "dmic1",
 613                .stream_name = "DMIC1 Capture",
 614                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 615                                | SND_SOC_DAIFMT_CBM_CFM,
 616                .dpcm_capture = 1,
 617                .ops = &cz_rt5682_dmic1_cap_ops,
 618                SND_SOC_DAILINK_REG(designware2, adau, platform),
 619        },
 620};
 621
 622static const struct snd_soc_dapm_widget cz_widgets[] = {
 623        SND_SOC_DAPM_HP("Headphones", NULL),
 624        SND_SOC_DAPM_SPK("Speakers", NULL),
 625        SND_SOC_DAPM_MIC("Headset Mic", NULL),
 626        SND_SOC_DAPM_MIC("Int Mic", NULL),
 627};
 628
 629static const struct snd_soc_dapm_route cz_audio_route[] = {
 630        {"Headphones", NULL, "HPL"},
 631        {"Headphones", NULL, "HPR"},
 632        {"MIC", NULL, "Headset Mic"},
 633        {"Speakers", NULL, "Speaker"},
 634        {"PDM_DAT", NULL, "Int Mic"},
 635};
 636
 637static const struct snd_soc_dapm_route cz_rt5682_audio_route[] = {
 638        {"Headphones", NULL, "HPOL"},
 639        {"Headphones", NULL, "HPOR"},
 640        {"IN1P", NULL, "Headset Mic"},
 641        {"Speakers", NULL, "Speaker"},
 642        {"PDM_DAT", NULL, "Int Mic"},
 643};
 644
 645static const struct snd_kcontrol_new cz_mc_controls[] = {
 646        SOC_DAPM_PIN_SWITCH("Headphones"),
 647        SOC_DAPM_PIN_SWITCH("Speakers"),
 648        SOC_DAPM_PIN_SWITCH("Headset Mic"),
 649        SOC_DAPM_PIN_SWITCH("Int Mic"),
 650};
 651
 652static struct snd_soc_card cz_card = {
 653        .name = "acpd7219m98357",
 654        .owner = THIS_MODULE,
 655        .dai_link = cz_dai_7219_98357,
 656        .num_links = ARRAY_SIZE(cz_dai_7219_98357),
 657        .dapm_widgets = cz_widgets,
 658        .num_dapm_widgets = ARRAY_SIZE(cz_widgets),
 659        .dapm_routes = cz_audio_route,
 660        .num_dapm_routes = ARRAY_SIZE(cz_audio_route),
 661        .controls = cz_mc_controls,
 662        .num_controls = ARRAY_SIZE(cz_mc_controls),
 663};
 664
 665static struct snd_soc_card cz_rt5682_card = {
 666        .name = "acpr5682m98357",
 667        .owner = THIS_MODULE,
 668        .dai_link = cz_dai_5682_98357,
 669        .num_links = ARRAY_SIZE(cz_dai_5682_98357),
 670        .dapm_widgets = cz_widgets,
 671        .num_dapm_widgets = ARRAY_SIZE(cz_widgets),
 672        .dapm_routes = cz_rt5682_audio_route,
 673        .controls = cz_mc_controls,
 674        .num_controls = ARRAY_SIZE(cz_mc_controls),
 675};
 676
 677void *acp_soc_is_rltk_max(struct device *dev)
 678{
 679        const struct acpi_device_id *match;
 680
 681        match = acpi_match_device(dev->driver->acpi_match_table, dev);
 682        if (!match)
 683                return NULL;
 684        return (void *)match->driver_data;
 685}
 686
 687static struct regulator_consumer_supply acp_da7219_supplies[] = {
 688        REGULATOR_SUPPLY("VDD", "i2c-DLGS7219:00"),
 689        REGULATOR_SUPPLY("VDDMIC", "i2c-DLGS7219:00"),
 690        REGULATOR_SUPPLY("VDDIO", "i2c-DLGS7219:00"),
 691        REGULATOR_SUPPLY("IOVDD", "ADAU7002:00"),
 692};
 693
 694static struct regulator_init_data acp_da7219_data = {
 695        .constraints = {
 696                .always_on = 1,
 697        },
 698        .num_consumer_supplies = ARRAY_SIZE(acp_da7219_supplies),
 699        .consumer_supplies = acp_da7219_supplies,
 700};
 701
 702static struct regulator_config acp_da7219_cfg = {
 703        .init_data = &acp_da7219_data,
 704};
 705
 706static struct regulator_ops acp_da7219_ops = {
 707};
 708
 709static const struct regulator_desc acp_da7219_desc = {
 710        .name = "reg-fixed-1.8V",
 711        .type = REGULATOR_VOLTAGE,
 712        .owner = THIS_MODULE,
 713        .ops = &acp_da7219_ops,
 714        .fixed_uV = 1800000, /* 1.8V */
 715        .n_voltages = 1,
 716};
 717
 718static int cz_probe(struct platform_device *pdev)
 719{
 720        int ret;
 721        struct snd_soc_card *card;
 722        struct acp_platform_info *machine;
 723        struct regulator_dev *rdev;
 724        struct device *dev = &pdev->dev;
 725
 726        card = (struct snd_soc_card *)acp_soc_is_rltk_max(dev);
 727        if (!card)
 728                return -ENODEV;
 729        if (!strcmp(card->name, "acpd7219m98357")) {
 730                acp_da7219_cfg.dev = &pdev->dev;
 731                rdev = devm_regulator_register(&pdev->dev, &acp_da7219_desc,
 732                                               &acp_da7219_cfg);
 733                if (IS_ERR(rdev)) {
 734                        dev_err(&pdev->dev, "Failed to register regulator: %d\n",
 735                                (int)PTR_ERR(rdev));
 736                        return -EINVAL;
 737                }
 738        }
 739
 740        machine = devm_kzalloc(&pdev->dev, sizeof(struct acp_platform_info),
 741                               GFP_KERNEL);
 742        if (!machine)
 743                return -ENOMEM;
 744        card->dev = &pdev->dev;
 745        platform_set_drvdata(pdev, card);
 746        snd_soc_card_set_drvdata(card, machine);
 747        ret = devm_snd_soc_register_card(&pdev->dev, card);
 748        if (ret) {
 749                if (ret != -EPROBE_DEFER)
 750                        dev_err(&pdev->dev,
 751                                "devm_snd_soc_register_card(%s) failed: %d\n",
 752                                card->name, ret);
 753                else
 754                        dev_dbg(&pdev->dev,
 755                                "devm_snd_soc_register_card(%s) probe deferred: %d\n",
 756                                card->name, ret);
 757                return ret;
 758        }
 759        bt_uart_enable = !device_property_read_bool(&pdev->dev,
 760                                                    "bt-pad-enable");
 761        return 0;
 762}
 763
 764#ifdef CONFIG_ACPI
 765static const struct acpi_device_id cz_audio_acpi_match[] = {
 766        { "AMD7219", (unsigned long)&cz_card },
 767        { "AMDI5682", (unsigned long)&cz_rt5682_card},
 768        {},
 769};
 770MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match);
 771#endif
 772
 773static struct platform_driver cz_pcm_driver = {
 774        .driver = {
 775                .name = "cz-da7219-max98357a",
 776                .acpi_match_table = ACPI_PTR(cz_audio_acpi_match),
 777                .pm = &snd_soc_pm_ops,
 778        },
 779        .probe = cz_probe,
 780};
 781
 782module_platform_driver(cz_pcm_driver);
 783
 784MODULE_AUTHOR("akshu.agrawal@amd.com");
 785MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
 786MODULE_DESCRIPTION("DA7219, RT5682 & MAX98357A audio support");
 787MODULE_LICENSE("GPL v2");
 788