Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Intel Broxton-P I2S Machine Driver
0004  *
0005  * Copyright (C) 2016, Intel Corporation. All rights reserved.
0006  *
0007  * Modified from:
0008  *   Intel Skylake I2S Machine driver
0009  */
0010 
0011 #include <linux/input.h>
0012 #include <linux/module.h>
0013 #include <linux/platform_device.h>
0014 #include <sound/core.h>
0015 #include <sound/jack.h>
0016 #include <sound/pcm.h>
0017 #include <sound/pcm_params.h>
0018 #include <sound/soc.h>
0019 #include <sound/soc-acpi.h>
0020 #include "../../codecs/hdac_hdmi.h"
0021 #include "../../codecs/da7219.h"
0022 #include "../../codecs/da7219-aad.h"
0023 #include "../common/soc-intel-quirks.h"
0024 #include "hda_dsp_common.h"
0025 
0026 #define BXT_DIALOG_CODEC_DAI    "da7219-hifi"
0027 #define BXT_MAXIM_CODEC_DAI "HiFi"
0028 #define MAX98390_DEV0_NAME  "i2c-MX98390:00"
0029 #define MAX98390_DEV1_NAME  "i2c-MX98390:01"
0030 #define DUAL_CHANNEL        2
0031 #define QUAD_CHANNEL        4
0032 
0033 #define SPKAMP_MAX98357A    1
0034 #define SPKAMP_MAX98390 2
0035 
0036 static struct snd_soc_jack broxton_headset;
0037 static struct snd_soc_jack broxton_hdmi[3];
0038 
0039 struct bxt_hdmi_pcm {
0040     struct list_head head;
0041     struct snd_soc_dai *codec_dai;
0042     int device;
0043 };
0044 
0045 struct bxt_card_private {
0046     struct list_head hdmi_pcm_list;
0047     bool common_hdmi_codec_drv;
0048     int spkamp;
0049 };
0050 
0051 enum {
0052     BXT_DPCM_AUDIO_PB = 0,
0053     BXT_DPCM_AUDIO_CP,
0054     BXT_DPCM_AUDIO_HS_PB,
0055     BXT_DPCM_AUDIO_REF_CP,
0056     BXT_DPCM_AUDIO_DMIC_CP,
0057     BXT_DPCM_AUDIO_HDMI1_PB,
0058     BXT_DPCM_AUDIO_HDMI2_PB,
0059     BXT_DPCM_AUDIO_HDMI3_PB,
0060 };
0061 
0062 static int platform_clock_control(struct snd_soc_dapm_widget *w,
0063     struct snd_kcontrol *k, int  event)
0064 {
0065     int ret = 0;
0066     struct snd_soc_dapm_context *dapm = w->dapm;
0067     struct snd_soc_card *card = dapm->card;
0068     struct snd_soc_dai *codec_dai;
0069 
0070     codec_dai = snd_soc_card_get_codec_dai(card, BXT_DIALOG_CODEC_DAI);
0071     if (!codec_dai) {
0072         dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
0073         return -EIO;
0074     }
0075 
0076     if (SND_SOC_DAPM_EVENT_OFF(event)) {
0077         ret = snd_soc_dai_set_pll(codec_dai, 0,
0078             DA7219_SYSCLK_MCLK, 0, 0);
0079         if (ret)
0080             dev_err(card->dev, "failed to stop PLL: %d\n", ret);
0081     } else if(SND_SOC_DAPM_EVENT_ON(event)) {
0082         ret = snd_soc_dai_set_pll(codec_dai, 0,
0083             DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304);
0084         if (ret)
0085             dev_err(card->dev, "failed to start PLL: %d\n", ret);
0086     }
0087 
0088     return ret;
0089 }
0090 
0091 static const struct snd_kcontrol_new broxton_controls[] = {
0092     SOC_DAPM_PIN_SWITCH("Headphone Jack"),
0093     SOC_DAPM_PIN_SWITCH("Headset Mic"),
0094 };
0095 
0096 static const struct snd_kcontrol_new max98357a_controls[] = {
0097     SOC_DAPM_PIN_SWITCH("Spk"),
0098 };
0099 
0100 static const struct snd_kcontrol_new max98390_controls[] = {
0101     SOC_DAPM_PIN_SWITCH("Left Spk"),
0102     SOC_DAPM_PIN_SWITCH("Right Spk"),
0103 };
0104 
0105 static const struct snd_soc_dapm_widget broxton_widgets[] = {
0106     SND_SOC_DAPM_HP("Headphone Jack", NULL),
0107     SND_SOC_DAPM_MIC("Headset Mic", NULL),
0108     SND_SOC_DAPM_MIC("SoC DMIC", NULL),
0109     SND_SOC_DAPM_SPK("HDMI1", NULL),
0110     SND_SOC_DAPM_SPK("HDMI2", NULL),
0111     SND_SOC_DAPM_SPK("HDMI3", NULL),
0112     SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
0113             platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU),
0114 };
0115 
0116 static const struct snd_soc_dapm_widget max98357a_widgets[] = {
0117     SND_SOC_DAPM_SPK("Spk", NULL),
0118 };
0119 
0120 static const struct snd_soc_dapm_widget max98390_widgets[] = {
0121     SND_SOC_DAPM_SPK("Left Spk", NULL),
0122     SND_SOC_DAPM_SPK("Right Spk", NULL),
0123 };
0124 
0125 static const struct snd_soc_dapm_route audio_map[] = {
0126     /* HP jack connectors - unknown if we have jack detection */
0127     {"Headphone Jack", NULL, "HPL"},
0128     {"Headphone Jack", NULL, "HPR"},
0129 
0130     /* other jacks */
0131     {"MIC", NULL, "Headset Mic"},
0132 
0133     /* digital mics */
0134     {"DMic", NULL, "SoC DMIC"},
0135 
0136     /* CODEC BE connections */
0137     {"HDMI1", NULL, "hif5-0 Output"},
0138     {"HDMI2", NULL, "hif6-0 Output"},
0139     {"HDMI2", NULL, "hif7-0 Output"},
0140 
0141     {"hifi3", NULL, "iDisp3 Tx"},
0142     {"iDisp3 Tx", NULL, "iDisp3_out"},
0143     {"hifi2", NULL, "iDisp2 Tx"},
0144     {"iDisp2 Tx", NULL, "iDisp2_out"},
0145     {"hifi1", NULL, "iDisp1 Tx"},
0146     {"iDisp1 Tx", NULL, "iDisp1_out"},
0147 
0148     /* DMIC */
0149     {"dmic01_hifi", NULL, "DMIC01 Rx"},
0150     {"DMIC01 Rx", NULL, "DMIC AIF"},
0151 
0152     { "Headphone Jack", NULL, "Platform Clock" },
0153     { "Headset Mic", NULL, "Platform Clock" },
0154 };
0155 
0156 static const struct snd_soc_dapm_route max98357a_routes[] = {
0157     /* speaker */
0158     {"Spk", NULL, "Speaker"},
0159 };
0160 
0161 static const struct snd_soc_dapm_route max98390_routes[] = {
0162     /* Speaker */
0163     {"Left Spk", NULL, "Left BE_OUT"},
0164     {"Right Spk", NULL, "Right BE_OUT"},
0165 };
0166 
0167 static const struct snd_soc_dapm_route broxton_map[] = {
0168     {"HiFi Playback", NULL, "ssp5 Tx"},
0169     {"ssp5 Tx", NULL, "codec0_out"},
0170 
0171     {"Playback", NULL, "ssp1 Tx"},
0172     {"ssp1 Tx", NULL, "codec1_out"},
0173 
0174     {"codec0_in", NULL, "ssp1 Rx"},
0175     {"ssp1 Rx", NULL, "Capture"},
0176 };
0177 
0178 static const struct snd_soc_dapm_route gemini_map[] = {
0179     {"HiFi Playback", NULL, "ssp1 Tx"},
0180     {"ssp1 Tx", NULL, "codec0_out"},
0181 
0182     {"Playback", NULL, "ssp2 Tx"},
0183     {"ssp2 Tx", NULL, "codec1_out"},
0184 
0185     {"codec0_in", NULL, "ssp2 Rx"},
0186     {"ssp2 Rx", NULL, "Capture"},
0187 };
0188 
0189 static struct snd_soc_jack_pin jack_pins[] = {
0190     {
0191         .pin    = "Headphone Jack",
0192         .mask   = SND_JACK_HEADPHONE,
0193     },
0194     {
0195         .pin    = "Headset Mic",
0196         .mask   = SND_JACK_MICROPHONE,
0197     },
0198 };
0199 
0200 static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
0201             struct snd_pcm_hw_params *params)
0202 {
0203     struct snd_interval *rate = hw_param_interval(params,
0204             SNDRV_PCM_HW_PARAM_RATE);
0205     struct snd_interval *chan = hw_param_interval(params,
0206             SNDRV_PCM_HW_PARAM_CHANNELS);
0207     struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
0208 
0209     /* The ADSP will convert the FE rate to 48k, stereo */
0210     rate->min = rate->max = 48000;
0211     chan->min = chan->max = DUAL_CHANNEL;
0212 
0213     /* set SSP to 24 bit */
0214     snd_mask_none(fmt);
0215     snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
0216 
0217     return 0;
0218 }
0219 
0220 static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
0221 {
0222     int ret;
0223     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0224     struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
0225     int clk_freq;
0226 
0227     /* Configure sysclk for codec */
0228     if (soc_intel_is_cml())
0229         clk_freq = 24000000;
0230     else
0231         clk_freq = 19200000;
0232 
0233     ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq,
0234                      SND_SOC_CLOCK_IN);
0235 
0236     if (ret) {
0237         dev_err(rtd->dev, "can't set codec sysclk configuration\n");
0238         return ret;
0239     }
0240 
0241     /*
0242      * Headset buttons map to the google Reference headset.
0243      * These can be configured by userspace.
0244      */
0245     ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
0246                      SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
0247                      SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT,
0248                      &broxton_headset,
0249                      jack_pins,
0250                      ARRAY_SIZE(jack_pins));
0251     if (ret) {
0252         dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
0253         return ret;
0254     }
0255 
0256     snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0257     snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
0258     snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
0259     snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_3,
0260              KEY_VOICECOMMAND);
0261 
0262     da7219_aad_jack_det(component, &broxton_headset);
0263 
0264     snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
0265 
0266     return ret;
0267 }
0268 
0269 static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd)
0270 {
0271     struct bxt_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
0272     struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
0273     struct bxt_hdmi_pcm *pcm;
0274 
0275     pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
0276     if (!pcm)
0277         return -ENOMEM;
0278 
0279     pcm->device = BXT_DPCM_AUDIO_HDMI1_PB + dai->id;
0280     pcm->codec_dai = dai;
0281 
0282     list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
0283 
0284     return 0;
0285 }
0286 
0287 static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd)
0288 {
0289     struct snd_soc_dapm_context *dapm;
0290     struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component;
0291 
0292     dapm = snd_soc_component_get_dapm(component);
0293     snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
0294 
0295     return 0;
0296 }
0297 
0298 static const unsigned int rates[] = {
0299     48000,
0300 };
0301 
0302 static const struct snd_pcm_hw_constraint_list constraints_rates = {
0303     .count = ARRAY_SIZE(rates),
0304     .list  = rates,
0305     .mask = 0,
0306 };
0307 
0308 static const unsigned int channels[] = {
0309     DUAL_CHANNEL,
0310 };
0311 
0312 static const struct snd_pcm_hw_constraint_list constraints_channels = {
0313     .count = ARRAY_SIZE(channels),
0314     .list = channels,
0315     .mask = 0,
0316 };
0317 
0318 static const unsigned int channels_quad[] = {
0319     QUAD_CHANNEL,
0320 };
0321 
0322 static const struct snd_pcm_hw_constraint_list constraints_channels_quad = {
0323     .count = ARRAY_SIZE(channels_quad),
0324     .list = channels_quad,
0325     .mask = 0,
0326 };
0327 
0328 static int bxt_fe_startup(struct snd_pcm_substream *substream)
0329 {
0330     struct snd_pcm_runtime *runtime = substream->runtime;
0331 
0332     /*
0333      * On this platform for PCM device we support,
0334      * 48Khz
0335      * stereo
0336      * 16 bit audio
0337      */
0338 
0339     runtime->hw.channels_max = DUAL_CHANNEL;
0340     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0341                        &constraints_channels);
0342 
0343     runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
0344     snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
0345 
0346     snd_pcm_hw_constraint_list(runtime, 0,
0347                 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
0348 
0349     return 0;
0350 }
0351 
0352 static const struct snd_soc_ops broxton_da7219_fe_ops = {
0353     .startup = bxt_fe_startup,
0354 };
0355 
0356 static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
0357             struct snd_pcm_hw_params *params)
0358 {
0359     struct snd_interval *chan = hw_param_interval(params,
0360                         SNDRV_PCM_HW_PARAM_CHANNELS);
0361     if (params_channels(params) == 2)
0362         chan->min = chan->max = 2;
0363     else
0364         chan->min = chan->max = 4;
0365 
0366     return 0;
0367 }
0368 
0369 static int broxton_dmic_startup(struct snd_pcm_substream *substream)
0370 {
0371     struct snd_pcm_runtime *runtime = substream->runtime;
0372 
0373     runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
0374     snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
0375             &constraints_channels_quad);
0376 
0377     return snd_pcm_hw_constraint_list(substream->runtime, 0,
0378             SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
0379 }
0380 
0381 static const struct snd_soc_ops broxton_dmic_ops = {
0382     .startup = broxton_dmic_startup,
0383 };
0384 
0385 static const unsigned int rates_16000[] = {
0386     16000,
0387 };
0388 
0389 static const struct snd_pcm_hw_constraint_list constraints_16000 = {
0390     .count = ARRAY_SIZE(rates_16000),
0391     .list  = rates_16000,
0392 };
0393 
0394 static const unsigned int ch_mono[] = {
0395     1,
0396 };
0397 
0398 static const struct snd_pcm_hw_constraint_list constraints_refcap = {
0399     .count = ARRAY_SIZE(ch_mono),
0400     .list  = ch_mono,
0401 };
0402 
0403 static int broxton_refcap_startup(struct snd_pcm_substream *substream)
0404 {
0405     substream->runtime->hw.channels_max = 1;
0406     snd_pcm_hw_constraint_list(substream->runtime, 0,
0407                    SNDRV_PCM_HW_PARAM_CHANNELS,
0408                    &constraints_refcap);
0409 
0410     return snd_pcm_hw_constraint_list(substream->runtime, 0,
0411             SNDRV_PCM_HW_PARAM_RATE,
0412             &constraints_16000);
0413 };
0414 
0415 static const struct snd_soc_ops broxton_refcap_ops = {
0416     .startup = broxton_refcap_startup,
0417 };
0418 
0419 /* broxton digital audio interface glue - connects codec <--> CPU */
0420 SND_SOC_DAILINK_DEF(dummy,
0421     DAILINK_COMP_ARRAY(COMP_DUMMY()));
0422 
0423 SND_SOC_DAILINK_DEF(system,
0424     DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
0425 
0426 SND_SOC_DAILINK_DEF(system2,
0427     DAILINK_COMP_ARRAY(COMP_CPU("System Pin2")));
0428 
0429 SND_SOC_DAILINK_DEF(reference,
0430     DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin")));
0431 
0432 SND_SOC_DAILINK_DEF(dmic,
0433     DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
0434 
0435 SND_SOC_DAILINK_DEF(hdmi1,
0436     DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin")));
0437 
0438 SND_SOC_DAILINK_DEF(hdmi2,
0439     DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin")));
0440 
0441 SND_SOC_DAILINK_DEF(hdmi3,
0442     DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin")));
0443 
0444  /* Back End DAI */
0445 SND_SOC_DAILINK_DEF(ssp5_pin,
0446     DAILINK_COMP_ARRAY(COMP_CPU("SSP5 Pin")));
0447 SND_SOC_DAILINK_DEF(ssp5_codec,
0448     DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00",
0449                       BXT_MAXIM_CODEC_DAI)));
0450 SND_SOC_DAILINK_DEF(max98390_codec,
0451     DAILINK_COMP_ARRAY(
0452     /* Left */  COMP_CODEC(MAX98390_DEV0_NAME, "max98390-aif1"),
0453     /* Right */ COMP_CODEC(MAX98390_DEV1_NAME, "max98390-aif1")));
0454 
0455 SND_SOC_DAILINK_DEF(ssp1_pin,
0456     DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
0457 SND_SOC_DAILINK_DEF(ssp1_codec,
0458     DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00",
0459                       BXT_DIALOG_CODEC_DAI)));
0460 
0461 SND_SOC_DAILINK_DEF(dmic_pin,
0462     DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
0463 
0464 SND_SOC_DAILINK_DEF(dmic16k_pin,
0465     DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin")));
0466 
0467 SND_SOC_DAILINK_DEF(dmic_codec,
0468     DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
0469 
0470 SND_SOC_DAILINK_DEF(idisp1_pin,
0471     DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
0472 SND_SOC_DAILINK_DEF(idisp1_codec,
0473     DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1")));
0474 
0475 SND_SOC_DAILINK_DEF(idisp2_pin,
0476     DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
0477 SND_SOC_DAILINK_DEF(idisp2_codec,
0478     DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
0479                       "intel-hdmi-hifi2")));
0480 
0481 SND_SOC_DAILINK_DEF(idisp3_pin,
0482     DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
0483 SND_SOC_DAILINK_DEF(idisp3_codec,
0484     DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
0485                       "intel-hdmi-hifi3")));
0486 
0487 SND_SOC_DAILINK_DEF(platform,
0488     DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0")));
0489 
0490 static struct snd_soc_dai_link broxton_dais[] = {
0491     /* Front End DAI links */
0492     [BXT_DPCM_AUDIO_PB] =
0493     {
0494         .name = "Bxt Audio Port",
0495         .stream_name = "Audio",
0496         .dynamic = 1,
0497         .nonatomic = 1,
0498         .init = broxton_da7219_fe_init,
0499         .trigger = {
0500             SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
0501         .dpcm_playback = 1,
0502         .ops = &broxton_da7219_fe_ops,
0503         SND_SOC_DAILINK_REG(system, dummy, platform),
0504     },
0505     [BXT_DPCM_AUDIO_CP] =
0506     {
0507         .name = "Bxt Audio Capture Port",
0508         .stream_name = "Audio Record",
0509         .dynamic = 1,
0510         .nonatomic = 1,
0511         .trigger = {
0512             SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
0513         .dpcm_capture = 1,
0514         .ops = &broxton_da7219_fe_ops,
0515         SND_SOC_DAILINK_REG(system, dummy, platform),
0516     },
0517     [BXT_DPCM_AUDIO_HS_PB] = {
0518         .name = "Bxt Audio Headset Playback",
0519         .stream_name = "Headset Playback",
0520         .dynamic = 1,
0521         .nonatomic = 1,
0522         .trigger = {
0523             SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
0524         .dpcm_playback = 1,
0525         .ops = &broxton_da7219_fe_ops,
0526         SND_SOC_DAILINK_REG(system2, dummy, platform),
0527     },
0528     [BXT_DPCM_AUDIO_REF_CP] =
0529     {
0530         .name = "Bxt Audio Reference cap",
0531         .stream_name = "Refcap",
0532         .init = NULL,
0533         .dpcm_capture = 1,
0534         .nonatomic = 1,
0535         .dynamic = 1,
0536         .ops = &broxton_refcap_ops,
0537         SND_SOC_DAILINK_REG(reference, dummy, platform),
0538     },
0539     [BXT_DPCM_AUDIO_DMIC_CP] =
0540     {
0541         .name = "Bxt Audio DMIC cap",
0542         .stream_name = "dmiccap",
0543         .init = NULL,
0544         .dpcm_capture = 1,
0545         .nonatomic = 1,
0546         .dynamic = 1,
0547         .ops = &broxton_dmic_ops,
0548         SND_SOC_DAILINK_REG(dmic, dummy, platform),
0549     },
0550     [BXT_DPCM_AUDIO_HDMI1_PB] =
0551     {
0552         .name = "Bxt HDMI Port1",
0553         .stream_name = "Hdmi1",
0554         .dpcm_playback = 1,
0555         .init = NULL,
0556         .nonatomic = 1,
0557         .dynamic = 1,
0558         SND_SOC_DAILINK_REG(hdmi1, dummy, platform),
0559     },
0560     [BXT_DPCM_AUDIO_HDMI2_PB] =
0561     {
0562         .name = "Bxt HDMI Port2",
0563         .stream_name = "Hdmi2",
0564         .dpcm_playback = 1,
0565         .init = NULL,
0566         .nonatomic = 1,
0567         .dynamic = 1,
0568         SND_SOC_DAILINK_REG(hdmi2, dummy, platform),
0569     },
0570     [BXT_DPCM_AUDIO_HDMI3_PB] =
0571     {
0572         .name = "Bxt HDMI Port3",
0573         .stream_name = "Hdmi3",
0574         .dpcm_playback = 1,
0575         .init = NULL,
0576         .nonatomic = 1,
0577         .dynamic = 1,
0578         SND_SOC_DAILINK_REG(hdmi3, dummy, platform),
0579     },
0580     /* Back End DAI links */
0581     {
0582         /* SSP5 - Codec */
0583         .name = "SSP5-Codec",
0584         .id = 0,
0585         .no_pcm = 1,
0586         .dai_fmt = SND_SOC_DAIFMT_I2S |
0587             SND_SOC_DAIFMT_NB_NF |
0588             SND_SOC_DAIFMT_CBC_CFC,
0589         .ignore_pmdown_time = 1,
0590         .be_hw_params_fixup = broxton_ssp_fixup,
0591         .dpcm_playback = 1,
0592         SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform),
0593     },
0594     {
0595         /* SSP1 - Codec */
0596         .name = "SSP1-Codec",
0597         .id = 1,
0598         .no_pcm = 1,
0599         .init = broxton_da7219_codec_init,
0600         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
0601             SND_SOC_DAIFMT_CBC_CFC,
0602         .ignore_pmdown_time = 1,
0603         .be_hw_params_fixup = broxton_ssp_fixup,
0604         .dpcm_playback = 1,
0605         .dpcm_capture = 1,
0606         SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
0607     },
0608     {
0609         .name = "dmic01",
0610         .id = 2,
0611         .ignore_suspend = 1,
0612         .be_hw_params_fixup = broxton_dmic_fixup,
0613         .dpcm_capture = 1,
0614         .no_pcm = 1,
0615         SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
0616     },
0617     {
0618         .name = "iDisp1",
0619         .id = 3,
0620         .init = broxton_hdmi_init,
0621         .dpcm_playback = 1,
0622         .no_pcm = 1,
0623         SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
0624     },
0625     {
0626         .name = "iDisp2",
0627         .id = 4,
0628         .init = broxton_hdmi_init,
0629         .dpcm_playback = 1,
0630         .no_pcm = 1,
0631         SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
0632     },
0633     {
0634         .name = "iDisp3",
0635         .id = 5,
0636         .init = broxton_hdmi_init,
0637         .dpcm_playback = 1,
0638         .no_pcm = 1,
0639         SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
0640     },
0641     {
0642         .name = "dmic16k",
0643         .id = 6,
0644         .be_hw_params_fixup = broxton_dmic_fixup,
0645         .dpcm_capture = 1,
0646         .no_pcm = 1,
0647         SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform),
0648     },
0649 };
0650 
0651 static struct snd_soc_codec_conf max98390_codec_confs[] = {
0652     {
0653         .dlc = COMP_CODEC_CONF(MAX98390_DEV0_NAME),
0654         .name_prefix = "Left",
0655     },
0656     {
0657         .dlc = COMP_CODEC_CONF(MAX98390_DEV1_NAME),
0658         .name_prefix = "Right",
0659     },
0660 };
0661 
0662 #define NAME_SIZE   32
0663 static int bxt_card_late_probe(struct snd_soc_card *card)
0664 {
0665     struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
0666     struct bxt_hdmi_pcm *pcm;
0667     struct snd_soc_component *component = NULL;
0668     const struct snd_kcontrol_new *controls;
0669     const struct snd_soc_dapm_widget *widgets;
0670     const struct snd_soc_dapm_route *routes;
0671     int num_controls, num_widgets, num_routes, err, i = 0;
0672     char jack_name[NAME_SIZE];
0673 
0674     switch (ctx->spkamp) {
0675     case SPKAMP_MAX98357A:
0676         controls = max98357a_controls;
0677         num_controls = ARRAY_SIZE(max98357a_controls);
0678         widgets = max98357a_widgets;
0679         num_widgets = ARRAY_SIZE(max98357a_widgets);
0680         routes = max98357a_routes;
0681         num_routes = ARRAY_SIZE(max98357a_routes);
0682         break;
0683     case SPKAMP_MAX98390:
0684         controls = max98390_controls;
0685         num_controls = ARRAY_SIZE(max98390_controls);
0686         widgets = max98390_widgets;
0687         num_widgets = ARRAY_SIZE(max98390_widgets);
0688         routes = max98390_routes;
0689         num_routes = ARRAY_SIZE(max98390_routes);
0690         break;
0691     default:
0692         dev_err(card->dev, "Invalid speaker amplifier %d\n", ctx->spkamp);
0693         return -EINVAL;
0694     }
0695 
0696     err = snd_soc_dapm_new_controls(&card->dapm, widgets, num_widgets);
0697     if (err) {
0698         dev_err(card->dev, "Fail to new widgets\n");
0699         return err;
0700     }
0701 
0702     err = snd_soc_add_card_controls(card, controls, num_controls);
0703     if (err) {
0704         dev_err(card->dev, "Fail to add controls\n");
0705         return err;
0706     }
0707 
0708     err = snd_soc_dapm_add_routes(&card->dapm, routes, num_routes);
0709     if (err) {
0710         dev_err(card->dev, "Fail to add routes\n");
0711         return err;
0712     }
0713 
0714     if (soc_intel_is_glk())
0715         snd_soc_dapm_add_routes(&card->dapm, gemini_map,
0716                     ARRAY_SIZE(gemini_map));
0717     else
0718         snd_soc_dapm_add_routes(&card->dapm, broxton_map,
0719                     ARRAY_SIZE(broxton_map));
0720 
0721     if (list_empty(&ctx->hdmi_pcm_list))
0722         return -EINVAL;
0723 
0724     if (ctx->common_hdmi_codec_drv) {
0725         pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
0726                        head);
0727         component = pcm->codec_dai->component;
0728         return hda_dsp_hdmi_build_controls(card, component);
0729     }
0730 
0731     list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
0732         component = pcm->codec_dai->component;
0733         snprintf(jack_name, sizeof(jack_name),
0734             "HDMI/DP, pcm=%d Jack", pcm->device);
0735         err = snd_soc_card_jack_new(card, jack_name,
0736                     SND_JACK_AVOUT, &broxton_hdmi[i]);
0737 
0738         if (err)
0739             return err;
0740 
0741         err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
0742                         &broxton_hdmi[i]);
0743         if (err < 0)
0744             return err;
0745 
0746         i++;
0747     }
0748 
0749     return hdac_hdmi_jack_port_init(component, &card->dapm);
0750 }
0751 
0752 /* broxton audio machine driver for SPT + da7219 */
0753 static struct snd_soc_card broxton_audio_card = {
0754     .name = "bxtda7219max",
0755     .owner = THIS_MODULE,
0756     .dai_link = broxton_dais,
0757     .num_links = ARRAY_SIZE(broxton_dais),
0758     .controls = broxton_controls,
0759     .num_controls = ARRAY_SIZE(broxton_controls),
0760     .dapm_widgets = broxton_widgets,
0761     .num_dapm_widgets = ARRAY_SIZE(broxton_widgets),
0762     .dapm_routes = audio_map,
0763     .num_dapm_routes = ARRAY_SIZE(audio_map),
0764     .fully_routed = true,
0765     .late_probe = bxt_card_late_probe,
0766 };
0767 
0768 static int broxton_audio_probe(struct platform_device *pdev)
0769 {
0770     struct bxt_card_private *ctx;
0771     struct snd_soc_acpi_mach *mach;
0772     const char *platform_name;
0773     int ret;
0774 
0775     ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
0776     if (!ctx)
0777         return -ENOMEM;
0778 
0779     INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
0780 
0781     if (acpi_dev_present("MX98390", NULL, -1))
0782         ctx->spkamp = SPKAMP_MAX98390;
0783     else
0784         ctx->spkamp = SPKAMP_MAX98357A;
0785 
0786     broxton_audio_card.dev = &pdev->dev;
0787     snd_soc_card_set_drvdata(&broxton_audio_card, ctx);
0788     if (soc_intel_is_glk()) {
0789         unsigned int i;
0790 
0791         broxton_audio_card.name = "glkda7219max";
0792         /* Fixup the SSP entries for geminilake */
0793         for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
0794             /* MAXIM_CODEC is connected to SSP1. */
0795             if (!strcmp(broxton_dais[i].codecs->dai_name,
0796                     BXT_MAXIM_CODEC_DAI)) {
0797                 broxton_dais[i].name = "SSP1-Codec";
0798                 broxton_dais[i].cpus->dai_name = "SSP1 Pin";
0799             }
0800             /* DIALOG_CODE is connected to SSP2 */
0801             else if (!strcmp(broxton_dais[i].codecs->dai_name,
0802                      BXT_DIALOG_CODEC_DAI)) {
0803                 broxton_dais[i].name = "SSP2-Codec";
0804                 broxton_dais[i].cpus->dai_name = "SSP2 Pin";
0805             }
0806         }
0807     } else if (soc_intel_is_cml()) {
0808         unsigned int i;
0809 
0810         if (ctx->spkamp == SPKAMP_MAX98390) {
0811             broxton_audio_card.name = "cml_max98390_da7219";
0812 
0813             broxton_audio_card.codec_conf = max98390_codec_confs;
0814             broxton_audio_card.num_configs = ARRAY_SIZE(max98390_codec_confs);
0815         } else
0816             broxton_audio_card.name = "cmlda7219max";
0817 
0818         for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
0819             /* MAXIM_CODEC is connected to SSP1. */
0820             if (!strcmp(broxton_dais[i].codecs->dai_name,
0821                     BXT_MAXIM_CODEC_DAI)) {
0822                 broxton_dais[i].name = "SSP1-Codec";
0823                 broxton_dais[i].cpus->dai_name = "SSP1 Pin";
0824 
0825                 if (ctx->spkamp == SPKAMP_MAX98390) {
0826                     broxton_dais[i].codecs = max98390_codec;
0827                     broxton_dais[i].num_codecs = ARRAY_SIZE(max98390_codec);
0828                     broxton_dais[i].dpcm_capture = 1;
0829                 }
0830             }
0831             /* DIALOG_CODEC is connected to SSP0 */
0832             else if (!strcmp(broxton_dais[i].codecs->dai_name,
0833                     BXT_DIALOG_CODEC_DAI)) {
0834                 broxton_dais[i].name = "SSP0-Codec";
0835                 broxton_dais[i].cpus->dai_name = "SSP0 Pin";
0836             }
0837         }
0838     }
0839 
0840     /* override platform name, if required */
0841     mach = pdev->dev.platform_data;
0842     platform_name = mach->mach_params.platform;
0843 
0844     ret = snd_soc_fixup_dai_links_platform_name(&broxton_audio_card,
0845                             platform_name);
0846     if (ret)
0847         return ret;
0848 
0849     ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
0850 
0851     return devm_snd_soc_register_card(&pdev->dev, &broxton_audio_card);
0852 }
0853 
0854 static const struct platform_device_id bxt_board_ids[] = {
0855     { .name = "bxt_da7219_mx98357a" },
0856     { .name = "glk_da7219_mx98357a" },
0857     { .name = "cml_da7219_mx98357a" },
0858     { }
0859 };
0860 MODULE_DEVICE_TABLE(platform, bxt_board_ids);
0861 
0862 static struct platform_driver broxton_audio = {
0863     .probe = broxton_audio_probe,
0864     .driver = {
0865         .name = "bxt_da7219_max98357a",
0866         .pm = &snd_soc_pm_ops,
0867     },
0868     .id_table = bxt_board_ids,
0869 };
0870 module_platform_driver(broxton_audio)
0871 
0872 /* Module information */
0873 MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode");
0874 MODULE_AUTHOR("Sathyanarayana Nujella <sathyanarayana.nujella@intel.com>");
0875 MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>");
0876 MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
0877 MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
0878 MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
0879 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
0880 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
0881 MODULE_LICENSE("GPL v2");
0882 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);