root/sound/soc/intel/boards/bxt_da7219_max98357a.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. platform_clock_control
  2. broxton_ssp_fixup
  3. broxton_da7219_codec_init
  4. broxton_hdmi_init
  5. broxton_da7219_fe_init
  6. bxt_fe_startup
  7. broxton_dmic_fixup
  8. broxton_dmic_startup
  9. broxton_refcap_startup
  10. bxt_card_late_probe
  11. broxton_audio_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Intel Broxton-P I2S Machine Driver
   4  *
   5  * Copyright (C) 2016, Intel Corporation. All rights reserved.
   6  *
   7  * Modified from:
   8  *   Intel Skylake I2S Machine driver
   9  */
  10 
  11 #include <linux/input.h>
  12 #include <linux/module.h>
  13 #include <linux/platform_device.h>
  14 #include <sound/core.h>
  15 #include <sound/jack.h>
  16 #include <sound/pcm.h>
  17 #include <sound/pcm_params.h>
  18 #include <sound/soc.h>
  19 #include <sound/soc-acpi.h>
  20 #include "../../codecs/hdac_hdmi.h"
  21 #include "../../codecs/da7219.h"
  22 #include "../../codecs/da7219-aad.h"
  23 #include "../common/soc-intel-quirks.h"
  24 
  25 #define BXT_DIALOG_CODEC_DAI    "da7219-hifi"
  26 #define BXT_MAXIM_CODEC_DAI     "HiFi"
  27 #define DUAL_CHANNEL            2
  28 #define QUAD_CHANNEL            4
  29 
  30 static struct snd_soc_jack broxton_headset;
  31 static struct snd_soc_jack broxton_hdmi[3];
  32 
  33 struct bxt_hdmi_pcm {
  34         struct list_head head;
  35         struct snd_soc_dai *codec_dai;
  36         int device;
  37 };
  38 
  39 struct bxt_card_private {
  40         struct list_head hdmi_pcm_list;
  41 };
  42 
  43 enum {
  44         BXT_DPCM_AUDIO_PB = 0,
  45         BXT_DPCM_AUDIO_CP,
  46         BXT_DPCM_AUDIO_HS_PB,
  47         BXT_DPCM_AUDIO_REF_CP,
  48         BXT_DPCM_AUDIO_DMIC_CP,
  49         BXT_DPCM_AUDIO_HDMI1_PB,
  50         BXT_DPCM_AUDIO_HDMI2_PB,
  51         BXT_DPCM_AUDIO_HDMI3_PB,
  52 };
  53 
  54 static int platform_clock_control(struct snd_soc_dapm_widget *w,
  55         struct snd_kcontrol *k, int  event)
  56 {
  57         int ret = 0;
  58         struct snd_soc_dapm_context *dapm = w->dapm;
  59         struct snd_soc_card *card = dapm->card;
  60         struct snd_soc_dai *codec_dai;
  61 
  62         codec_dai = snd_soc_card_get_codec_dai(card, BXT_DIALOG_CODEC_DAI);
  63         if (!codec_dai) {
  64                 dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
  65                 return -EIO;
  66         }
  67 
  68         if (SND_SOC_DAPM_EVENT_OFF(event)) {
  69                 ret = snd_soc_dai_set_pll(codec_dai, 0,
  70                         DA7219_SYSCLK_MCLK, 0, 0);
  71                 if (ret)
  72                         dev_err(card->dev, "failed to stop PLL: %d\n", ret);
  73         } else if(SND_SOC_DAPM_EVENT_ON(event)) {
  74                 ret = snd_soc_dai_set_pll(codec_dai, 0,
  75                         DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304);
  76                 if (ret)
  77                         dev_err(card->dev, "failed to start PLL: %d\n", ret);
  78         }
  79 
  80         return ret;
  81 }
  82 
  83 static const struct snd_kcontrol_new broxton_controls[] = {
  84         SOC_DAPM_PIN_SWITCH("Headphone Jack"),
  85         SOC_DAPM_PIN_SWITCH("Headset Mic"),
  86         SOC_DAPM_PIN_SWITCH("Spk"),
  87 };
  88 
  89 static const struct snd_soc_dapm_widget broxton_widgets[] = {
  90         SND_SOC_DAPM_HP("Headphone Jack", NULL),
  91         SND_SOC_DAPM_MIC("Headset Mic", NULL),
  92         SND_SOC_DAPM_SPK("Spk", NULL),
  93         SND_SOC_DAPM_MIC("SoC DMIC", NULL),
  94         SND_SOC_DAPM_SPK("HDMI1", NULL),
  95         SND_SOC_DAPM_SPK("HDMI2", NULL),
  96         SND_SOC_DAPM_SPK("HDMI3", NULL),
  97         SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
  98                         platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU),
  99 };
 100 
 101 static const struct snd_soc_dapm_route audio_map[] = {
 102         /* HP jack connectors - unknown if we have jack detection */
 103         {"Headphone Jack", NULL, "HPL"},
 104         {"Headphone Jack", NULL, "HPR"},
 105 
 106         /* speaker */
 107         {"Spk", NULL, "Speaker"},
 108 
 109         /* other jacks */
 110         {"MIC", NULL, "Headset Mic"},
 111 
 112         /* digital mics */
 113         {"DMic", NULL, "SoC DMIC"},
 114 
 115         /* CODEC BE connections */
 116         {"HDMI1", NULL, "hif5-0 Output"},
 117         {"HDMI2", NULL, "hif6-0 Output"},
 118         {"HDMI2", NULL, "hif7-0 Output"},
 119 
 120         {"hifi3", NULL, "iDisp3 Tx"},
 121         {"iDisp3 Tx", NULL, "iDisp3_out"},
 122         {"hifi2", NULL, "iDisp2 Tx"},
 123         {"iDisp2 Tx", NULL, "iDisp2_out"},
 124         {"hifi1", NULL, "iDisp1 Tx"},
 125         {"iDisp1 Tx", NULL, "iDisp1_out"},
 126 
 127         /* DMIC */
 128         {"dmic01_hifi", NULL, "DMIC01 Rx"},
 129         {"DMIC01 Rx", NULL, "DMIC AIF"},
 130 
 131         { "Headphone Jack", NULL, "Platform Clock" },
 132         { "Headset Mic", NULL, "Platform Clock" },
 133 };
 134 
 135 static const struct snd_soc_dapm_route broxton_map[] = {
 136         {"HiFi Playback", NULL, "ssp5 Tx"},
 137         {"ssp5 Tx", NULL, "codec0_out"},
 138 
 139         {"Playback", NULL, "ssp1 Tx"},
 140         {"ssp1 Tx", NULL, "codec1_out"},
 141 
 142         {"codec0_in", NULL, "ssp1 Rx"},
 143         {"ssp1 Rx", NULL, "Capture"},
 144 };
 145 
 146 static const struct snd_soc_dapm_route gemini_map[] = {
 147         {"HiFi Playback", NULL, "ssp1 Tx"},
 148         {"ssp1 Tx", NULL, "codec0_out"},
 149 
 150         {"Playback", NULL, "ssp2 Tx"},
 151         {"ssp2 Tx", NULL, "codec1_out"},
 152 
 153         {"codec0_in", NULL, "ssp2 Rx"},
 154         {"ssp2 Rx", NULL, "Capture"},
 155 };
 156 
 157 static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
 158                         struct snd_pcm_hw_params *params)
 159 {
 160         struct snd_interval *rate = hw_param_interval(params,
 161                         SNDRV_PCM_HW_PARAM_RATE);
 162         struct snd_interval *channels = hw_param_interval(params,
 163                         SNDRV_PCM_HW_PARAM_CHANNELS);
 164         struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 165 
 166         /* The ADSP will convert the FE rate to 48k, stereo */
 167         rate->min = rate->max = 48000;
 168         channels->min = channels->max = DUAL_CHANNEL;
 169 
 170         /* set SSP to 24 bit */
 171         snd_mask_none(fmt);
 172         snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
 173 
 174         return 0;
 175 }
 176 
 177 static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
 178 {
 179         int ret;
 180         struct snd_soc_dai *codec_dai = rtd->codec_dai;
 181         struct snd_soc_component *component = rtd->codec_dai->component;
 182         int clk_freq;
 183 
 184         /* Configure sysclk for codec */
 185         if (soc_intel_is_cml())
 186                 clk_freq = 24000000;
 187         else
 188                 clk_freq = 19200000;
 189 
 190         ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq,
 191                                      SND_SOC_CLOCK_IN);
 192 
 193         if (ret) {
 194                 dev_err(rtd->dev, "can't set codec sysclk configuration\n");
 195                 return ret;
 196         }
 197 
 198         /*
 199          * Headset buttons map to the google Reference headset.
 200          * These can be configured by userspace.
 201          */
 202         ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
 203                         SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 204                         SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT,
 205                         &broxton_headset, NULL, 0);
 206         if (ret) {
 207                 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
 208                 return ret;
 209         }
 210 
 211         snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
 212         snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
 213         snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
 214         snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_3,
 215                          KEY_VOICECOMMAND);
 216 
 217         da7219_aad_jack_det(component, &broxton_headset);
 218 
 219         snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 220 
 221         return ret;
 222 }
 223 
 224 static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd)
 225 {
 226         struct bxt_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 227         struct snd_soc_dai *dai = rtd->codec_dai;
 228         struct bxt_hdmi_pcm *pcm;
 229 
 230         pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
 231         if (!pcm)
 232                 return -ENOMEM;
 233 
 234         pcm->device = BXT_DPCM_AUDIO_HDMI1_PB + dai->id;
 235         pcm->codec_dai = dai;
 236 
 237         list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
 238 
 239         return 0;
 240 }
 241 
 242 static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd)
 243 {
 244         struct snd_soc_dapm_context *dapm;
 245         struct snd_soc_component *component = rtd->cpu_dai->component;
 246 
 247         dapm = snd_soc_component_get_dapm(component);
 248         snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
 249 
 250         return 0;
 251 }
 252 
 253 static const unsigned int rates[] = {
 254         48000,
 255 };
 256 
 257 static const struct snd_pcm_hw_constraint_list constraints_rates = {
 258         .count = ARRAY_SIZE(rates),
 259         .list  = rates,
 260         .mask = 0,
 261 };
 262 
 263 static const unsigned int channels[] = {
 264         DUAL_CHANNEL,
 265 };
 266 
 267 static const struct snd_pcm_hw_constraint_list constraints_channels = {
 268         .count = ARRAY_SIZE(channels),
 269         .list = channels,
 270         .mask = 0,
 271 };
 272 
 273 static const unsigned int channels_quad[] = {
 274         QUAD_CHANNEL,
 275 };
 276 
 277 static const struct snd_pcm_hw_constraint_list constraints_channels_quad = {
 278         .count = ARRAY_SIZE(channels_quad),
 279         .list = channels_quad,
 280         .mask = 0,
 281 };
 282 
 283 static int bxt_fe_startup(struct snd_pcm_substream *substream)
 284 {
 285         struct snd_pcm_runtime *runtime = substream->runtime;
 286 
 287         /*
 288          * On this platform for PCM device we support,
 289          * 48Khz
 290          * stereo
 291          * 16 bit audio
 292          */
 293 
 294         runtime->hw.channels_max = DUAL_CHANNEL;
 295         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 296                                            &constraints_channels);
 297 
 298         runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
 299         snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
 300 
 301         snd_pcm_hw_constraint_list(runtime, 0,
 302                                 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
 303 
 304         return 0;
 305 }
 306 
 307 static const struct snd_soc_ops broxton_da7219_fe_ops = {
 308         .startup = bxt_fe_startup,
 309 };
 310 
 311 static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
 312                         struct snd_pcm_hw_params *params)
 313 {
 314         struct snd_interval *channels = hw_param_interval(params,
 315                                                 SNDRV_PCM_HW_PARAM_CHANNELS);
 316         if (params_channels(params) == 2)
 317                 channels->min = channels->max = 2;
 318         else
 319                 channels->min = channels->max = 4;
 320 
 321         return 0;
 322 }
 323 
 324 static int broxton_dmic_startup(struct snd_pcm_substream *substream)
 325 {
 326         struct snd_pcm_runtime *runtime = substream->runtime;
 327 
 328         runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
 329         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 330                         &constraints_channels_quad);
 331 
 332         return snd_pcm_hw_constraint_list(substream->runtime, 0,
 333                         SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
 334 }
 335 
 336 static const struct snd_soc_ops broxton_dmic_ops = {
 337         .startup = broxton_dmic_startup,
 338 };
 339 
 340 static const unsigned int rates_16000[] = {
 341         16000,
 342 };
 343 
 344 static const struct snd_pcm_hw_constraint_list constraints_16000 = {
 345         .count = ARRAY_SIZE(rates_16000),
 346         .list  = rates_16000,
 347 };
 348 
 349 static const unsigned int ch_mono[] = {
 350         1,
 351 };
 352 
 353 static const struct snd_pcm_hw_constraint_list constraints_refcap = {
 354         .count = ARRAY_SIZE(ch_mono),
 355         .list  = ch_mono,
 356 };
 357 
 358 static int broxton_refcap_startup(struct snd_pcm_substream *substream)
 359 {
 360         substream->runtime->hw.channels_max = 1;
 361         snd_pcm_hw_constraint_list(substream->runtime, 0,
 362                                    SNDRV_PCM_HW_PARAM_CHANNELS,
 363                                    &constraints_refcap);
 364 
 365         return snd_pcm_hw_constraint_list(substream->runtime, 0,
 366                         SNDRV_PCM_HW_PARAM_RATE,
 367                         &constraints_16000);
 368 };
 369 
 370 static const struct snd_soc_ops broxton_refcap_ops = {
 371         .startup = broxton_refcap_startup,
 372 };
 373 
 374 /* broxton digital audio interface glue - connects codec <--> CPU */
 375 SND_SOC_DAILINK_DEF(dummy,
 376         DAILINK_COMP_ARRAY(COMP_DUMMY()));
 377 
 378 SND_SOC_DAILINK_DEF(system,
 379         DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
 380 
 381 SND_SOC_DAILINK_DEF(system2,
 382         DAILINK_COMP_ARRAY(COMP_CPU("System Pin2")));
 383 
 384 SND_SOC_DAILINK_DEF(reference,
 385         DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin")));
 386 
 387 SND_SOC_DAILINK_DEF(dmic,
 388         DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
 389 
 390 SND_SOC_DAILINK_DEF(hdmi1,
 391         DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin")));
 392 
 393 SND_SOC_DAILINK_DEF(hdmi2,
 394         DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin")));
 395 
 396 SND_SOC_DAILINK_DEF(hdmi3,
 397         DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin")));
 398 
 399  /* Back End DAI */
 400 SND_SOC_DAILINK_DEF(ssp5_pin,
 401         DAILINK_COMP_ARRAY(COMP_CPU("SSP5 Pin")));
 402 SND_SOC_DAILINK_DEF(ssp5_codec,
 403         DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00",
 404                                       BXT_MAXIM_CODEC_DAI)));
 405 
 406 SND_SOC_DAILINK_DEF(ssp1_pin,
 407         DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
 408 SND_SOC_DAILINK_DEF(ssp1_codec,
 409         DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00",
 410                                       BXT_DIALOG_CODEC_DAI)));
 411 
 412 SND_SOC_DAILINK_DEF(dmic_pin,
 413         DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
 414 
 415 SND_SOC_DAILINK_DEF(dmic16k_pin,
 416         DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin")));
 417 
 418 SND_SOC_DAILINK_DEF(dmic_codec,
 419         DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
 420 
 421 SND_SOC_DAILINK_DEF(idisp1_pin,
 422         DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
 423 SND_SOC_DAILINK_DEF(idisp1_codec,
 424         DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1")));
 425 
 426 SND_SOC_DAILINK_DEF(idisp2_pin,
 427         DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
 428 SND_SOC_DAILINK_DEF(idisp2_codec,
 429         DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
 430                                       "intel-hdmi-hifi2")));
 431 
 432 SND_SOC_DAILINK_DEF(idisp3_pin,
 433         DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
 434 SND_SOC_DAILINK_DEF(idisp3_codec,
 435         DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
 436                                       "intel-hdmi-hifi3")));
 437 
 438 SND_SOC_DAILINK_DEF(platform,
 439         DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0")));
 440 
 441 static struct snd_soc_dai_link broxton_dais[] = {
 442         /* Front End DAI links */
 443         [BXT_DPCM_AUDIO_PB] =
 444         {
 445                 .name = "Bxt Audio Port",
 446                 .stream_name = "Audio",
 447                 .dynamic = 1,
 448                 .nonatomic = 1,
 449                 .init = broxton_da7219_fe_init,
 450                 .trigger = {
 451                         SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 452                 .dpcm_playback = 1,
 453                 .ops = &broxton_da7219_fe_ops,
 454                 SND_SOC_DAILINK_REG(system, dummy, platform),
 455         },
 456         [BXT_DPCM_AUDIO_CP] =
 457         {
 458                 .name = "Bxt Audio Capture Port",
 459                 .stream_name = "Audio Record",
 460                 .dynamic = 1,
 461                 .nonatomic = 1,
 462                 .trigger = {
 463                         SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 464                 .dpcm_capture = 1,
 465                 .ops = &broxton_da7219_fe_ops,
 466                 SND_SOC_DAILINK_REG(system, dummy, platform),
 467         },
 468         [BXT_DPCM_AUDIO_HS_PB] = {
 469                 .name = "Bxt Audio Headset Playback",
 470                 .stream_name = "Headset Playback",
 471                 .dynamic = 1,
 472                 .nonatomic = 1,
 473                 .trigger = {
 474                         SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 475                 .dpcm_playback = 1,
 476                 .ops = &broxton_da7219_fe_ops,
 477                 SND_SOC_DAILINK_REG(system2, dummy, platform),
 478         },
 479         [BXT_DPCM_AUDIO_REF_CP] =
 480         {
 481                 .name = "Bxt Audio Reference cap",
 482                 .stream_name = "Refcap",
 483                 .init = NULL,
 484                 .dpcm_capture = 1,
 485                 .nonatomic = 1,
 486                 .dynamic = 1,
 487                 .ops = &broxton_refcap_ops,
 488                 SND_SOC_DAILINK_REG(reference, dummy, platform),
 489         },
 490         [BXT_DPCM_AUDIO_DMIC_CP] =
 491         {
 492                 .name = "Bxt Audio DMIC cap",
 493                 .stream_name = "dmiccap",
 494                 .init = NULL,
 495                 .dpcm_capture = 1,
 496                 .nonatomic = 1,
 497                 .dynamic = 1,
 498                 .ops = &broxton_dmic_ops,
 499                 SND_SOC_DAILINK_REG(dmic, dummy, platform),
 500         },
 501         [BXT_DPCM_AUDIO_HDMI1_PB] =
 502         {
 503                 .name = "Bxt HDMI Port1",
 504                 .stream_name = "Hdmi1",
 505                 .dpcm_playback = 1,
 506                 .init = NULL,
 507                 .nonatomic = 1,
 508                 .dynamic = 1,
 509                 SND_SOC_DAILINK_REG(hdmi1, dummy, platform),
 510         },
 511         [BXT_DPCM_AUDIO_HDMI2_PB] =
 512         {
 513                 .name = "Bxt HDMI Port2",
 514                 .stream_name = "Hdmi2",
 515                 .dpcm_playback = 1,
 516                 .init = NULL,
 517                 .nonatomic = 1,
 518                 .dynamic = 1,
 519                 SND_SOC_DAILINK_REG(hdmi2, dummy, platform),
 520         },
 521         [BXT_DPCM_AUDIO_HDMI3_PB] =
 522         {
 523                 .name = "Bxt HDMI Port3",
 524                 .stream_name = "Hdmi3",
 525                 .dpcm_playback = 1,
 526                 .init = NULL,
 527                 .nonatomic = 1,
 528                 .dynamic = 1,
 529                 SND_SOC_DAILINK_REG(hdmi3, dummy, platform),
 530         },
 531         /* Back End DAI links */
 532         {
 533                 /* SSP5 - Codec */
 534                 .name = "SSP5-Codec",
 535                 .id = 0,
 536                 .no_pcm = 1,
 537                 .dai_fmt = SND_SOC_DAIFMT_I2S |
 538                         SND_SOC_DAIFMT_NB_NF |
 539                         SND_SOC_DAIFMT_CBS_CFS,
 540                 .ignore_pmdown_time = 1,
 541                 .be_hw_params_fixup = broxton_ssp_fixup,
 542                 .dpcm_playback = 1,
 543                 SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform),
 544         },
 545         {
 546                 /* SSP1 - Codec */
 547                 .name = "SSP1-Codec",
 548                 .id = 1,
 549                 .no_pcm = 1,
 550                 .init = broxton_da7219_codec_init,
 551                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 552                         SND_SOC_DAIFMT_CBS_CFS,
 553                 .ignore_pmdown_time = 1,
 554                 .be_hw_params_fixup = broxton_ssp_fixup,
 555                 .dpcm_playback = 1,
 556                 .dpcm_capture = 1,
 557                 SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
 558         },
 559         {
 560                 .name = "dmic01",
 561                 .id = 2,
 562                 .ignore_suspend = 1,
 563                 .be_hw_params_fixup = broxton_dmic_fixup,
 564                 .dpcm_capture = 1,
 565                 .no_pcm = 1,
 566                 SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
 567         },
 568         {
 569                 .name = "iDisp1",
 570                 .id = 3,
 571                 .init = broxton_hdmi_init,
 572                 .dpcm_playback = 1,
 573                 .no_pcm = 1,
 574                 SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
 575         },
 576         {
 577                 .name = "iDisp2",
 578                 .id = 4,
 579                 .init = broxton_hdmi_init,
 580                 .dpcm_playback = 1,
 581                 .no_pcm = 1,
 582                 SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
 583         },
 584         {
 585                 .name = "iDisp3",
 586                 .id = 5,
 587                 .init = broxton_hdmi_init,
 588                 .dpcm_playback = 1,
 589                 .no_pcm = 1,
 590                 SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
 591         },
 592         {
 593                 .name = "dmic16k",
 594                 .id = 6,
 595                 .be_hw_params_fixup = broxton_dmic_fixup,
 596                 .dpcm_capture = 1,
 597                 .no_pcm = 1,
 598                 SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform),
 599         },
 600 };
 601 
 602 #define NAME_SIZE       32
 603 static int bxt_card_late_probe(struct snd_soc_card *card)
 604 {
 605         struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
 606         struct bxt_hdmi_pcm *pcm;
 607         struct snd_soc_component *component = NULL;
 608         int err, i = 0;
 609         char jack_name[NAME_SIZE];
 610 
 611         if (soc_intel_is_glk())
 612                 snd_soc_dapm_add_routes(&card->dapm, gemini_map,
 613                                         ARRAY_SIZE(gemini_map));
 614         else
 615                 snd_soc_dapm_add_routes(&card->dapm, broxton_map,
 616                                         ARRAY_SIZE(broxton_map));
 617 
 618         list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 619                 component = pcm->codec_dai->component;
 620                 snprintf(jack_name, sizeof(jack_name),
 621                         "HDMI/DP, pcm=%d Jack", pcm->device);
 622                 err = snd_soc_card_jack_new(card, jack_name,
 623                                         SND_JACK_AVOUT, &broxton_hdmi[i],
 624                                         NULL, 0);
 625 
 626                 if (err)
 627                         return err;
 628 
 629                 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 630                                                 &broxton_hdmi[i]);
 631                 if (err < 0)
 632                         return err;
 633 
 634                 i++;
 635         }
 636 
 637         if (!component)
 638                 return -EINVAL;
 639 
 640         return hdac_hdmi_jack_port_init(component, &card->dapm);
 641 }
 642 
 643 /* broxton audio machine driver for SPT + da7219 */
 644 static struct snd_soc_card broxton_audio_card = {
 645         .name = "bxtda7219max",
 646         .owner = THIS_MODULE,
 647         .dai_link = broxton_dais,
 648         .num_links = ARRAY_SIZE(broxton_dais),
 649         .controls = broxton_controls,
 650         .num_controls = ARRAY_SIZE(broxton_controls),
 651         .dapm_widgets = broxton_widgets,
 652         .num_dapm_widgets = ARRAY_SIZE(broxton_widgets),
 653         .dapm_routes = audio_map,
 654         .num_dapm_routes = ARRAY_SIZE(audio_map),
 655         .fully_routed = true,
 656         .late_probe = bxt_card_late_probe,
 657 };
 658 
 659 static int broxton_audio_probe(struct platform_device *pdev)
 660 {
 661         struct bxt_card_private *ctx;
 662         struct snd_soc_acpi_mach *mach;
 663         const char *platform_name;
 664         int ret;
 665 
 666         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
 667         if (!ctx)
 668                 return -ENOMEM;
 669 
 670         INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
 671 
 672         broxton_audio_card.dev = &pdev->dev;
 673         snd_soc_card_set_drvdata(&broxton_audio_card, ctx);
 674         if (soc_intel_is_glk()) {
 675                 unsigned int i;
 676 
 677                 broxton_audio_card.name = "glkda7219max";
 678                 /* Fixup the SSP entries for geminilake */
 679                 for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
 680                         /* MAXIM_CODEC is connected to SSP1. */
 681                         if (!strcmp(broxton_dais[i].codecs->dai_name,
 682                                     BXT_MAXIM_CODEC_DAI)) {
 683                                 broxton_dais[i].name = "SSP1-Codec";
 684                                 broxton_dais[i].cpus->dai_name = "SSP1 Pin";
 685                         }
 686                         /* DIALOG_CODE is connected to SSP2 */
 687                         else if (!strcmp(broxton_dais[i].codecs->dai_name,
 688                                          BXT_DIALOG_CODEC_DAI)) {
 689                                 broxton_dais[i].name = "SSP2-Codec";
 690                                 broxton_dais[i].cpus->dai_name = "SSP2 Pin";
 691                         }
 692                 }
 693         } else if (soc_intel_is_cml()) {
 694                 unsigned int i;
 695 
 696                 broxton_audio_card.name = "cmlda7219max";
 697 
 698                 for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
 699                         /* MAXIM_CODEC is connected to SSP1. */
 700                         if (!strcmp(broxton_dais[i].codecs->dai_name,
 701                                         BXT_MAXIM_CODEC_DAI)) {
 702                                 broxton_dais[i].name = "SSP1-Codec";
 703                                 broxton_dais[i].cpus->dai_name = "SSP1 Pin";
 704                         }
 705                         /* DIALOG_CODEC is connected to SSP0 */
 706                         else if (!strcmp(broxton_dais[i].codecs->dai_name,
 707                                         BXT_DIALOG_CODEC_DAI)) {
 708                                 broxton_dais[i].name = "SSP0-Codec";
 709                                 broxton_dais[i].cpus->dai_name = "SSP0 Pin";
 710                         }
 711                 }
 712         }
 713 
 714         /* override plaform name, if required */
 715         mach = (&pdev->dev)->platform_data;
 716         platform_name = mach->mach_params.platform;
 717 
 718         ret = snd_soc_fixup_dai_links_platform_name(&broxton_audio_card,
 719                                                     platform_name);
 720         if (ret)
 721                 return ret;
 722 
 723         return devm_snd_soc_register_card(&pdev->dev, &broxton_audio_card);
 724 }
 725 
 726 static const struct platform_device_id bxt_board_ids[] = {
 727         { .name = "bxt_da7219_max98357a" },
 728         { .name = "glk_da7219_max98357a" },
 729         { .name = "cml_da7219_max98357a" },
 730         { }
 731 };
 732 
 733 static struct platform_driver broxton_audio = {
 734         .probe = broxton_audio_probe,
 735         .driver = {
 736                 .name = "bxt_da7219_max98357a",
 737                 .pm = &snd_soc_pm_ops,
 738         },
 739         .id_table = bxt_board_ids,
 740 };
 741 module_platform_driver(broxton_audio)
 742 
 743 /* Module information */
 744 MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode");
 745 MODULE_AUTHOR("Sathyanarayana Nujella <sathyanarayana.nujella@intel.com>");
 746 MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>");
 747 MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
 748 MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
 749 MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
 750 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
 751 MODULE_LICENSE("GPL v2");
 752 MODULE_ALIAS("platform:bxt_da7219_max98357a");
 753 MODULE_ALIAS("platform:glk_da7219_max98357a");
 754 MODULE_ALIAS("platform:cml_da7219_max98357a");

/* [<][>][^][v][top][bottom][index][help] */