0001
0002
0003
0004
0005
0006
0007
0008
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
0127 {"Headphone Jack", NULL, "HPL"},
0128 {"Headphone Jack", NULL, "HPR"},
0129
0130
0131 {"MIC", NULL, "Headset Mic"},
0132
0133
0134 {"DMic", NULL, "SoC DMIC"},
0135
0136
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
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
0158 {"Spk", NULL, "Speaker"},
0159 };
0160
0161 static const struct snd_soc_dapm_route max98390_routes[] = {
0162
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
0210 rate->min = rate->max = 48000;
0211 chan->min = chan->max = DUAL_CHANNEL;
0212
0213
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
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
0243
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
0334
0335
0336
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
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
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 COMP_CODEC(MAX98390_DEV0_NAME, "max98390-aif1"),
0453 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
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
0581 {
0582
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
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
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
0793 for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
0794
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
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
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
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
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
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);