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

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

DEFINITIONS

This source file includes following definitions.
  1. broxton_rt298_fe_init
  2. broxton_rt298_codec_init
  3. broxton_hdmi_init
  4. broxton_ssp5_fixup
  5. broxton_rt298_hw_params
  6. broxton_dmic_fixup
  7. broxton_dmic_startup
  8. bxt_fe_startup
  9. bxt_card_late_probe
  10. broxton_audio_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Intel Broxton-P I2S Machine Driver
   4  *
   5  * Copyright (C) 2014-2016, Intel Corporation. All rights reserved.
   6  *
   7  * Modified from:
   8  *   Intel Skylake I2S Machine driver
   9  */
  10 
  11 #include <linux/module.h>
  12 #include <linux/platform_device.h>
  13 #include <sound/core.h>
  14 #include <sound/pcm.h>
  15 #include <sound/soc.h>
  16 #include <sound/soc-acpi.h>
  17 #include <sound/jack.h>
  18 #include <sound/pcm_params.h>
  19 #include "../../codecs/hdac_hdmi.h"
  20 #include "../../codecs/rt298.h"
  21 
  22 /* Headset jack detection DAPM pins */
  23 static struct snd_soc_jack broxton_headset;
  24 static struct snd_soc_jack broxton_hdmi[3];
  25 
  26 struct bxt_hdmi_pcm {
  27         struct list_head head;
  28         struct snd_soc_dai *codec_dai;
  29         int device;
  30 };
  31 
  32 struct bxt_rt286_private {
  33         struct list_head hdmi_pcm_list;
  34 };
  35 
  36 enum {
  37         BXT_DPCM_AUDIO_PB = 0,
  38         BXT_DPCM_AUDIO_CP,
  39         BXT_DPCM_AUDIO_REF_CP,
  40         BXT_DPCM_AUDIO_DMIC_CP,
  41         BXT_DPCM_AUDIO_HDMI1_PB,
  42         BXT_DPCM_AUDIO_HDMI2_PB,
  43         BXT_DPCM_AUDIO_HDMI3_PB,
  44 };
  45 
  46 static struct snd_soc_jack_pin broxton_headset_pins[] = {
  47         {
  48                 .pin = "Mic Jack",
  49                 .mask = SND_JACK_MICROPHONE,
  50         },
  51         {
  52                 .pin = "Headphone Jack",
  53                 .mask = SND_JACK_HEADPHONE,
  54         },
  55 };
  56 
  57 static const struct snd_kcontrol_new broxton_controls[] = {
  58         SOC_DAPM_PIN_SWITCH("Speaker"),
  59         SOC_DAPM_PIN_SWITCH("Headphone Jack"),
  60         SOC_DAPM_PIN_SWITCH("Mic Jack"),
  61 };
  62 
  63 static const struct snd_soc_dapm_widget broxton_widgets[] = {
  64         SND_SOC_DAPM_HP("Headphone Jack", NULL),
  65         SND_SOC_DAPM_SPK("Speaker", NULL),
  66         SND_SOC_DAPM_MIC("Mic Jack", NULL),
  67         SND_SOC_DAPM_MIC("DMIC2", NULL),
  68         SND_SOC_DAPM_MIC("SoC DMIC", NULL),
  69         SND_SOC_DAPM_SPK("HDMI1", NULL),
  70         SND_SOC_DAPM_SPK("HDMI2", NULL),
  71         SND_SOC_DAPM_SPK("HDMI3", NULL),
  72 };
  73 
  74 static const struct snd_soc_dapm_route broxton_rt298_map[] = {
  75         /* speaker */
  76         {"Speaker", NULL, "SPOR"},
  77         {"Speaker", NULL, "SPOL"},
  78 
  79         /* HP jack connectors - unknown if we have jack detect */
  80         {"Headphone Jack", NULL, "HPO Pin"},
  81 
  82         /* other jacks */
  83         {"MIC1", NULL, "Mic Jack"},
  84 
  85         /* digital mics */
  86         {"DMIC1 Pin", NULL, "DMIC2"},
  87         {"DMic", NULL, "SoC DMIC"},
  88 
  89         {"HDMI1", NULL, "hif5-0 Output"},
  90         {"HDMI2", NULL, "hif6-0 Output"},
  91         {"HDMI2", NULL, "hif7-0 Output"},
  92 
  93         /* CODEC BE connections */
  94         { "AIF1 Playback", NULL, "ssp5 Tx"},
  95         { "ssp5 Tx", NULL, "codec0_out"},
  96         { "ssp5 Tx", NULL, "codec1_out"},
  97 
  98         { "codec0_in", NULL, "ssp5 Rx" },
  99         { "ssp5 Rx", NULL, "AIF1 Capture" },
 100 
 101         { "dmic01_hifi", NULL, "DMIC01 Rx" },
 102         { "DMIC01 Rx", NULL, "Capture" },
 103 
 104         { "hifi3", NULL, "iDisp3 Tx"},
 105         { "iDisp3 Tx", NULL, "iDisp3_out"},
 106         { "hifi2", NULL, "iDisp2 Tx"},
 107         { "iDisp2 Tx", NULL, "iDisp2_out"},
 108         { "hifi1", NULL, "iDisp1 Tx"},
 109         { "iDisp1 Tx", NULL, "iDisp1_out"},
 110 };
 111 
 112 static const struct snd_soc_dapm_route geminilake_rt298_map[] = {
 113         /* speaker */
 114         {"Speaker", NULL, "SPOR"},
 115         {"Speaker", NULL, "SPOL"},
 116 
 117         /* HP jack connectors - unknown if we have jack detect */
 118         {"Headphone Jack", NULL, "HPO Pin"},
 119 
 120         /* other jacks */
 121         {"MIC1", NULL, "Mic Jack"},
 122 
 123         /* digital mics */
 124         {"DMIC1 Pin", NULL, "DMIC2"},
 125         {"DMic", NULL, "SoC DMIC"},
 126 
 127         {"HDMI1", NULL, "hif5-0 Output"},
 128         {"HDMI2", NULL, "hif6-0 Output"},
 129         {"HDMI2", NULL, "hif7-0 Output"},
 130 
 131         /* CODEC BE connections */
 132         { "AIF1 Playback", NULL, "ssp2 Tx"},
 133         { "ssp2 Tx", NULL, "codec0_out"},
 134         { "ssp2 Tx", NULL, "codec1_out"},
 135 
 136         { "codec0_in", NULL, "ssp2 Rx" },
 137         { "ssp2 Rx", NULL, "AIF1 Capture" },
 138 
 139         { "dmic01_hifi", NULL, "DMIC01 Rx" },
 140         { "DMIC01 Rx", NULL, "Capture" },
 141 
 142         { "dmic_voice", NULL, "DMIC16k Rx" },
 143         { "DMIC16k Rx", NULL, "Capture" },
 144 
 145         { "hifi3", NULL, "iDisp3 Tx"},
 146         { "iDisp3 Tx", NULL, "iDisp3_out"},
 147         { "hifi2", NULL, "iDisp2 Tx"},
 148         { "iDisp2 Tx", NULL, "iDisp2_out"},
 149         { "hifi1", NULL, "iDisp1 Tx"},
 150         { "iDisp1 Tx", NULL, "iDisp1_out"},
 151 };
 152 
 153 static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd)
 154 {
 155         struct snd_soc_dapm_context *dapm;
 156         struct snd_soc_component *component = rtd->cpu_dai->component;
 157 
 158         dapm = snd_soc_component_get_dapm(component);
 159         snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
 160 
 161         return 0;
 162 }
 163 
 164 static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd)
 165 {
 166         struct snd_soc_component *component = rtd->codec_dai->component;
 167         int ret = 0;
 168 
 169         ret = snd_soc_card_jack_new(rtd->card, "Headset",
 170                 SND_JACK_HEADSET | SND_JACK_BTN_0,
 171                 &broxton_headset,
 172                 broxton_headset_pins, ARRAY_SIZE(broxton_headset_pins));
 173 
 174         if (ret)
 175                 return ret;
 176 
 177         rt298_mic_detect(component, &broxton_headset);
 178 
 179         snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 180 
 181         return 0;
 182 }
 183 
 184 static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd)
 185 {
 186         struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 187         struct snd_soc_dai *dai = rtd->codec_dai;
 188         struct bxt_hdmi_pcm *pcm;
 189 
 190         pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
 191         if (!pcm)
 192                 return -ENOMEM;
 193 
 194         pcm->device = BXT_DPCM_AUDIO_HDMI1_PB + dai->id;
 195         pcm->codec_dai = dai;
 196 
 197         list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
 198 
 199         return 0;
 200 }
 201 
 202 static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime *rtd,
 203                         struct snd_pcm_hw_params *params)
 204 {
 205         struct snd_interval *rate = hw_param_interval(params,
 206                                         SNDRV_PCM_HW_PARAM_RATE);
 207         struct snd_interval *channels = hw_param_interval(params,
 208                                         SNDRV_PCM_HW_PARAM_CHANNELS);
 209         struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 210 
 211         /* The ADSP will covert the FE rate to 48k, stereo */
 212         rate->min = rate->max = 48000;
 213         channels->min = channels->max = 2;
 214 
 215         /* set SSP5 to 24 bit */
 216         snd_mask_none(fmt);
 217         snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
 218 
 219         return 0;
 220 }
 221 
 222 static int broxton_rt298_hw_params(struct snd_pcm_substream *substream,
 223         struct snd_pcm_hw_params *params)
 224 {
 225         struct snd_soc_pcm_runtime *rtd = substream->private_data;
 226         struct snd_soc_dai *codec_dai = rtd->codec_dai;
 227         int ret;
 228 
 229         ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL,
 230                                         19200000, SND_SOC_CLOCK_IN);
 231         if (ret < 0) {
 232                 dev_err(rtd->dev, "can't set codec sysclk configuration\n");
 233                 return ret;
 234         }
 235 
 236         return ret;
 237 }
 238 
 239 static const struct snd_soc_ops broxton_rt298_ops = {
 240         .hw_params = broxton_rt298_hw_params,
 241 };
 242 
 243 static const unsigned int rates[] = {
 244         48000,
 245 };
 246 
 247 static const struct snd_pcm_hw_constraint_list constraints_rates = {
 248         .count = ARRAY_SIZE(rates),
 249         .list  = rates,
 250         .mask = 0,
 251 };
 252 
 253 static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
 254                                 struct snd_pcm_hw_params *params)
 255 {
 256         struct snd_interval *channels = hw_param_interval(params,
 257                                                 SNDRV_PCM_HW_PARAM_CHANNELS);
 258         channels->min = channels->max = 4;
 259 
 260         return 0;
 261 }
 262 
 263 static const unsigned int channels_dmic[] = {
 264         1, 2, 3, 4,
 265 };
 266 
 267 static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
 268         .count = ARRAY_SIZE(channels_dmic),
 269         .list = channels_dmic,
 270         .mask = 0,
 271 };
 272 
 273 static int broxton_dmic_startup(struct snd_pcm_substream *substream)
 274 {
 275         struct snd_pcm_runtime *runtime = substream->runtime;
 276 
 277         runtime->hw.channels_max = 4;
 278         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 279                                         &constraints_dmic_channels);
 280 
 281         return snd_pcm_hw_constraint_list(substream->runtime, 0,
 282                                 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
 283 }
 284 
 285 static const struct snd_soc_ops broxton_dmic_ops = {
 286         .startup = broxton_dmic_startup,
 287 };
 288 
 289 static const unsigned int channels[] = {
 290         2,
 291 };
 292 
 293 static const struct snd_pcm_hw_constraint_list constraints_channels = {
 294         .count = ARRAY_SIZE(channels),
 295         .list = channels,
 296         .mask = 0,
 297 };
 298 
 299 static int bxt_fe_startup(struct snd_pcm_substream *substream)
 300 {
 301         struct snd_pcm_runtime *runtime = substream->runtime;
 302 
 303         /*
 304          * on this platform for PCM device we support:
 305          *      48Khz
 306          *      stereo
 307          *      16-bit audio
 308          */
 309 
 310         runtime->hw.channels_max = 2;
 311         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 312                                 &constraints_channels);
 313 
 314         runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
 315         snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
 316         snd_pcm_hw_constraint_list(runtime, 0,
 317                                 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
 318 
 319         return 0;
 320 }
 321 
 322 static const struct snd_soc_ops broxton_rt286_fe_ops = {
 323         .startup = bxt_fe_startup,
 324 };
 325 
 326 SND_SOC_DAILINK_DEF(dummy,
 327         DAILINK_COMP_ARRAY(COMP_DUMMY()));
 328 
 329 SND_SOC_DAILINK_DEF(system,
 330         DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
 331 
 332 SND_SOC_DAILINK_DEF(reference,
 333         DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin")));
 334 
 335 SND_SOC_DAILINK_DEF(dmic,
 336         DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
 337 
 338 SND_SOC_DAILINK_DEF(hdmi1,
 339         DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin")));
 340 
 341 SND_SOC_DAILINK_DEF(hdmi2,
 342         DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin")));
 343 
 344 SND_SOC_DAILINK_DEF(hdmi3,
 345         DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin")));
 346 
 347 SND_SOC_DAILINK_DEF(ssp5_pin,
 348         DAILINK_COMP_ARRAY(COMP_CPU("SSP5 Pin")));
 349 SND_SOC_DAILINK_DEF(ssp5_codec,
 350         DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00",
 351                                       "rt298-aif1")));
 352 
 353 SND_SOC_DAILINK_DEF(dmic_pin,
 354         DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
 355 
 356 SND_SOC_DAILINK_DEF(dmic_codec,
 357         DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec",
 358                                       "dmic-hifi")));
 359 
 360 SND_SOC_DAILINK_DEF(dmic16k,
 361         DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin")));
 362 
 363 SND_SOC_DAILINK_DEF(idisp1_pin,
 364         DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
 365 SND_SOC_DAILINK_DEF(idisp1_codec,
 366         DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
 367                                       "intel-hdmi-hifi1")));
 368 
 369 SND_SOC_DAILINK_DEF(idisp2_pin,
 370         DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
 371 SND_SOC_DAILINK_DEF(idisp2_codec,
 372         DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
 373                                       "intel-hdmi-hifi2")));
 374 
 375 SND_SOC_DAILINK_DEF(idisp3_pin,
 376         DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
 377 SND_SOC_DAILINK_DEF(idisp3_codec,
 378         DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
 379                                       "intel-hdmi-hifi3")));
 380 
 381 SND_SOC_DAILINK_DEF(platform,
 382         DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0")));
 383 
 384 /* broxton digital audio interface glue - connects codec <--> CPU */
 385 static struct snd_soc_dai_link broxton_rt298_dais[] = {
 386         /* Front End DAI links */
 387         [BXT_DPCM_AUDIO_PB] =
 388         {
 389                 .name = "Bxt Audio Port",
 390                 .stream_name = "Audio",
 391                 .nonatomic = 1,
 392                 .dynamic = 1,
 393                 .init = broxton_rt298_fe_init,
 394                 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 395                 .dpcm_playback = 1,
 396                 .ops = &broxton_rt286_fe_ops,
 397                 SND_SOC_DAILINK_REG(system, dummy, platform),
 398         },
 399         [BXT_DPCM_AUDIO_CP] =
 400         {
 401                 .name = "Bxt Audio Capture Port",
 402                 .stream_name = "Audio Record",
 403                 .nonatomic = 1,
 404                 .dynamic = 1,
 405                 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 406                 .dpcm_capture = 1,
 407                 .ops = &broxton_rt286_fe_ops,
 408                 SND_SOC_DAILINK_REG(system, dummy, platform),
 409         },
 410         [BXT_DPCM_AUDIO_REF_CP] =
 411         {
 412                 .name = "Bxt Audio Reference cap",
 413                 .stream_name = "refcap",
 414                 .init = NULL,
 415                 .dpcm_capture = 1,
 416                 .nonatomic = 1,
 417                 .dynamic = 1,
 418                 SND_SOC_DAILINK_REG(reference, dummy, platform),
 419         },
 420         [BXT_DPCM_AUDIO_DMIC_CP] =
 421         {
 422                 .name = "Bxt Audio DMIC cap",
 423                 .stream_name = "dmiccap",
 424                 .init = NULL,
 425                 .dpcm_capture = 1,
 426                 .nonatomic = 1,
 427                 .dynamic = 1,
 428                 .ops = &broxton_dmic_ops,
 429                 SND_SOC_DAILINK_REG(dmic, dummy, platform),
 430         },
 431         [BXT_DPCM_AUDIO_HDMI1_PB] =
 432         {
 433                 .name = "Bxt HDMI Port1",
 434                 .stream_name = "Hdmi1",
 435                 .dpcm_playback = 1,
 436                 .init = NULL,
 437                 .nonatomic = 1,
 438                 .dynamic = 1,
 439                 SND_SOC_DAILINK_REG(hdmi1, dummy, platform),
 440         },
 441         [BXT_DPCM_AUDIO_HDMI2_PB] =
 442         {
 443                 .name = "Bxt HDMI Port2",
 444                 .stream_name = "Hdmi2",
 445                 .dpcm_playback = 1,
 446                 .init = NULL,
 447                 .nonatomic = 1,
 448                 .dynamic = 1,
 449                 SND_SOC_DAILINK_REG(hdmi2, dummy, platform),
 450         },
 451         [BXT_DPCM_AUDIO_HDMI3_PB] =
 452         {
 453                 .name = "Bxt HDMI Port3",
 454                 .stream_name = "Hdmi3",
 455                 .dpcm_playback = 1,
 456                 .init = NULL,
 457                 .nonatomic = 1,
 458                 .dynamic = 1,
 459                 SND_SOC_DAILINK_REG(hdmi3, dummy, platform),
 460         },
 461         /* Back End DAI links */
 462         {
 463                 /* SSP5 - Codec */
 464                 .name = "SSP5-Codec",
 465                 .id = 0,
 466                 .no_pcm = 1,
 467                 .init = broxton_rt298_codec_init,
 468                 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF |
 469                                                 SND_SOC_DAIFMT_CBS_CFS,
 470                 .ignore_pmdown_time = 1,
 471                 .be_hw_params_fixup = broxton_ssp5_fixup,
 472                 .ops = &broxton_rt298_ops,
 473                 .dpcm_playback = 1,
 474                 .dpcm_capture = 1,
 475                 SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform),
 476         },
 477         {
 478                 .name = "dmic01",
 479                 .id = 1,
 480                 .be_hw_params_fixup = broxton_dmic_fixup,
 481                 .ignore_suspend = 1,
 482                 .dpcm_capture = 1,
 483                 .no_pcm = 1,
 484                 SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
 485         },
 486         {
 487                 .name = "dmic16k",
 488                 .id = 2,
 489                 .be_hw_params_fixup = broxton_dmic_fixup,
 490                 .ignore_suspend = 1,
 491                 .dpcm_capture = 1,
 492                 .no_pcm = 1,
 493                 SND_SOC_DAILINK_REG(dmic16k, dmic_codec, platform),
 494         },
 495         {
 496                 .name = "iDisp1",
 497                 .id = 3,
 498                 .init = broxton_hdmi_init,
 499                 .dpcm_playback = 1,
 500                 .no_pcm = 1,
 501                 SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
 502         },
 503         {
 504                 .name = "iDisp2",
 505                 .id = 4,
 506                 .init = broxton_hdmi_init,
 507                 .dpcm_playback = 1,
 508                 .no_pcm = 1,
 509                 SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
 510         },
 511         {
 512                 .name = "iDisp3",
 513                 .id = 5,
 514                 .init = broxton_hdmi_init,
 515                 .dpcm_playback = 1,
 516                 .no_pcm = 1,
 517                 SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
 518         },
 519 };
 520 
 521 #define NAME_SIZE       32
 522 static int bxt_card_late_probe(struct snd_soc_card *card)
 523 {
 524         struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
 525         struct bxt_hdmi_pcm *pcm;
 526         struct snd_soc_component *component = NULL;
 527         int err, i = 0;
 528         char jack_name[NAME_SIZE];
 529 
 530         list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 531                 component = pcm->codec_dai->component;
 532                 snprintf(jack_name, sizeof(jack_name),
 533                         "HDMI/DP, pcm=%d Jack", pcm->device);
 534                 err = snd_soc_card_jack_new(card, jack_name,
 535                                         SND_JACK_AVOUT, &broxton_hdmi[i],
 536                                         NULL, 0);
 537 
 538                 if (err)
 539                         return err;
 540 
 541                 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 542                                                 &broxton_hdmi[i]);
 543                 if (err < 0)
 544                         return err;
 545 
 546                 i++;
 547         }
 548 
 549         if (!component)
 550                 return -EINVAL;
 551 
 552         return hdac_hdmi_jack_port_init(component, &card->dapm);
 553 }
 554 
 555 
 556 /* broxton audio machine driver for SPT + RT298S */
 557 static struct snd_soc_card broxton_rt298 = {
 558         .name = "broxton-rt298",
 559         .dai_link = broxton_rt298_dais,
 560         .num_links = ARRAY_SIZE(broxton_rt298_dais),
 561         .controls = broxton_controls,
 562         .num_controls = ARRAY_SIZE(broxton_controls),
 563         .dapm_widgets = broxton_widgets,
 564         .num_dapm_widgets = ARRAY_SIZE(broxton_widgets),
 565         .dapm_routes = broxton_rt298_map,
 566         .num_dapm_routes = ARRAY_SIZE(broxton_rt298_map),
 567         .fully_routed = true,
 568         .late_probe = bxt_card_late_probe,
 569 
 570 };
 571 
 572 static struct snd_soc_card geminilake_rt298 = {
 573         .name = "geminilake-rt298",
 574         .dai_link = broxton_rt298_dais,
 575         .num_links = ARRAY_SIZE(broxton_rt298_dais),
 576         .controls = broxton_controls,
 577         .num_controls = ARRAY_SIZE(broxton_controls),
 578         .dapm_widgets = broxton_widgets,
 579         .num_dapm_widgets = ARRAY_SIZE(broxton_widgets),
 580         .dapm_routes = geminilake_rt298_map,
 581         .num_dapm_routes = ARRAY_SIZE(geminilake_rt298_map),
 582         .fully_routed = true,
 583         .late_probe = bxt_card_late_probe,
 584 };
 585 
 586 static int broxton_audio_probe(struct platform_device *pdev)
 587 {
 588         struct bxt_rt286_private *ctx;
 589         struct snd_soc_card *card =
 590                         (struct snd_soc_card *)pdev->id_entry->driver_data;
 591         struct snd_soc_acpi_mach *mach;
 592         const char *platform_name;
 593         int ret;
 594         int i;
 595 
 596         for (i = 0; i < ARRAY_SIZE(broxton_rt298_dais); i++) {
 597                 if (!strncmp(card->dai_link[i].codecs->name, "i2c-INT343A:00",
 598                              I2C_NAME_SIZE)) {
 599                         if (!strncmp(card->name, "broxton-rt298",
 600                                      PLATFORM_NAME_SIZE)) {
 601                                 card->dai_link[i].name = "SSP5-Codec";
 602                                 card->dai_link[i].cpus->dai_name = "SSP5 Pin";
 603                         } else if (!strncmp(card->name, "geminilake-rt298",
 604                                             PLATFORM_NAME_SIZE)) {
 605                                 card->dai_link[i].name = "SSP2-Codec";
 606                                 card->dai_link[i].cpus->dai_name = "SSP2 Pin";
 607                         }
 608                 }
 609         }
 610 
 611         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
 612         if (!ctx)
 613                 return -ENOMEM;
 614 
 615         INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
 616 
 617         card->dev = &pdev->dev;
 618         snd_soc_card_set_drvdata(card, ctx);
 619 
 620         /* override plaform name, if required */
 621         mach = (&pdev->dev)->platform_data;
 622         platform_name = mach->mach_params.platform;
 623 
 624         ret = snd_soc_fixup_dai_links_platform_name(card,
 625                                                     platform_name);
 626         if (ret)
 627                 return ret;
 628 
 629         return devm_snd_soc_register_card(&pdev->dev, card);
 630 }
 631 
 632 static const struct platform_device_id bxt_board_ids[] = {
 633         { .name = "bxt_alc298s_i2s", .driver_data =
 634                                 (unsigned long)&broxton_rt298 },
 635         { .name = "glk_alc298s_i2s", .driver_data =
 636                                 (unsigned long)&geminilake_rt298 },
 637         {}
 638 };
 639 
 640 static struct platform_driver broxton_audio = {
 641         .probe = broxton_audio_probe,
 642         .driver = {
 643                 .name = "bxt_alc298s_i2s",
 644                 .pm = &snd_soc_pm_ops,
 645         },
 646         .id_table = bxt_board_ids,
 647 };
 648 module_platform_driver(broxton_audio)
 649 
 650 /* Module information */
 651 MODULE_AUTHOR("Ramesh Babu <Ramesh.Babu@intel.com>");
 652 MODULE_AUTHOR("Senthilnathan Veppur <senthilnathanx.veppur@intel.com>");
 653 MODULE_DESCRIPTION("Intel SST Audio for Broxton");
 654 MODULE_LICENSE("GPL v2");
 655 MODULE_ALIAS("platform:bxt_alc298s_i2s");
 656 MODULE_ALIAS("platform:glk_alc298s_i2s");

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