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

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

DEFINITIONS

This source file includes following definitions.
  1. geminilake_ssp_fixup
  2. geminilake_rt5682_codec_init
  3. geminilake_rt5682_hw_params
  4. geminilake_hdmi_init
  5. geminilake_rt5682_fe_init
  6. geminilake_dmic_fixup
  7. geminilake_dmic_startup
  8. geminilake_refcap_startup
  9. glk_card_late_probe
  10. geminilake_audio_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright(c) 2018 Intel Corporation.
   3 
   4 /*
   5  * Intel Geminilake I2S Machine Driver with MAX98357A & RT5682 Codecs
   6  *
   7  * Modified from:
   8  *   Intel Apollolake 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/rt5682.h"
  21 #include "../../codecs/hdac_hdmi.h"
  22 
  23 /* The platform clock outputs 19.2Mhz clock to codec as I2S MCLK */
  24 #define GLK_PLAT_CLK_FREQ 19200000
  25 #define RT5682_PLL_FREQ (48000 * 512)
  26 #define GLK_REALTEK_CODEC_DAI "rt5682-aif1"
  27 #define GLK_MAXIM_CODEC_DAI "HiFi"
  28 #define MAXIM_DEV0_NAME "MX98357A:00"
  29 #define DUAL_CHANNEL 2
  30 #define QUAD_CHANNEL 4
  31 #define NAME_SIZE 32
  32 
  33 static struct snd_soc_jack geminilake_hdmi[3];
  34 
  35 struct glk_hdmi_pcm {
  36         struct list_head head;
  37         struct snd_soc_dai *codec_dai;
  38         int device;
  39 };
  40 
  41 struct glk_card_private {
  42         struct snd_soc_jack geminilake_headset;
  43         struct list_head hdmi_pcm_list;
  44 };
  45 
  46 enum {
  47         GLK_DPCM_AUDIO_PB = 0,
  48         GLK_DPCM_AUDIO_CP,
  49         GLK_DPCM_AUDIO_HS_PB,
  50         GLK_DPCM_AUDIO_ECHO_REF_CP,
  51         GLK_DPCM_AUDIO_REF_CP,
  52         GLK_DPCM_AUDIO_DMIC_CP,
  53         GLK_DPCM_AUDIO_HDMI1_PB,
  54         GLK_DPCM_AUDIO_HDMI2_PB,
  55         GLK_DPCM_AUDIO_HDMI3_PB,
  56 };
  57 
  58 static const struct snd_kcontrol_new geminilake_controls[] = {
  59         SOC_DAPM_PIN_SWITCH("Headphone Jack"),
  60         SOC_DAPM_PIN_SWITCH("Headset Mic"),
  61         SOC_DAPM_PIN_SWITCH("Spk"),
  62 };
  63 
  64 static const struct snd_soc_dapm_widget geminilake_widgets[] = {
  65         SND_SOC_DAPM_HP("Headphone Jack", NULL),
  66         SND_SOC_DAPM_MIC("Headset Mic", NULL),
  67         SND_SOC_DAPM_SPK("Spk", 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 geminilake_map[] = {
  75         /* HP jack connectors - unknown if we have jack detection */
  76         { "Headphone Jack", NULL, "HPOL" },
  77         { "Headphone Jack", NULL, "HPOR" },
  78 
  79         /* speaker */
  80         { "Spk", NULL, "Speaker" },
  81 
  82         /* other jacks */
  83         { "IN1P", NULL, "Headset Mic" },
  84 
  85         /* digital mics */
  86         { "DMic", NULL, "SoC DMIC" },
  87 
  88         /* CODEC BE connections */
  89         { "HiFi Playback", NULL, "ssp1 Tx" },
  90         { "ssp1 Tx", NULL, "codec0_out" },
  91 
  92         { "AIF1 Playback", NULL, "ssp2 Tx" },
  93         { "ssp2 Tx", NULL, "codec1_out" },
  94 
  95         { "codec0_in", NULL, "ssp2 Rx" },
  96         { "ssp2 Rx", NULL, "AIF1 Capture" },
  97 
  98         { "HDMI1", NULL, "hif5-0 Output" },
  99         { "HDMI2", NULL, "hif6-0 Output" },
 100         { "HDMI2", NULL, "hif7-0 Output" },
 101 
 102         { "hifi3", NULL, "iDisp3 Tx" },
 103         { "iDisp3 Tx", NULL, "iDisp3_out" },
 104         { "hifi2", NULL, "iDisp2 Tx" },
 105         { "iDisp2 Tx", NULL, "iDisp2_out" },
 106         { "hifi1", NULL, "iDisp1 Tx" },
 107         { "iDisp1 Tx", NULL, "iDisp1_out" },
 108 
 109         /* DMIC */
 110         { "dmic01_hifi", NULL, "DMIC01 Rx" },
 111         { "DMIC01 Rx", NULL, "DMIC AIF" },
 112 };
 113 
 114 static int geminilake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
 115                         struct snd_pcm_hw_params *params)
 116 {
 117         struct snd_interval *rate = hw_param_interval(params,
 118                         SNDRV_PCM_HW_PARAM_RATE);
 119         struct snd_interval *channels = hw_param_interval(params,
 120                         SNDRV_PCM_HW_PARAM_CHANNELS);
 121         struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 122 
 123         /* The ADSP will convert the FE rate to 48k, stereo */
 124         rate->min = rate->max = 48000;
 125         channels->min = channels->max = DUAL_CHANNEL;
 126 
 127         /* set SSP to 24 bit */
 128         snd_mask_none(fmt);
 129         snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
 130 
 131         return 0;
 132 }
 133 
 134 static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
 135 {
 136         struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 137         struct snd_soc_component *component = rtd->codec_dai->component;
 138         struct snd_soc_dai *codec_dai = rtd->codec_dai;
 139         struct snd_soc_jack *jack;
 140         int ret;
 141 
 142         ret = snd_soc_dai_set_pll(codec_dai, 0, RT5682_PLL1_S_MCLK,
 143                                         GLK_PLAT_CLK_FREQ, RT5682_PLL_FREQ);
 144         if (ret < 0) {
 145                 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
 146                 return ret;
 147         }
 148 
 149         /* Configure sysclk for codec */
 150         ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
 151                                         RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
 152         if (ret < 0)
 153                 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
 154 
 155         /*
 156          * Headset buttons map to the google Reference headset.
 157          * These can be configured by userspace.
 158          */
 159         ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
 160                         SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 161                         SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT,
 162                         &ctx->geminilake_headset, NULL, 0);
 163         if (ret) {
 164                 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
 165                 return ret;
 166         }
 167 
 168         jack = &ctx->geminilake_headset;
 169 
 170         snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
 171         snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
 172         snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
 173         snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 174 
 175         ret = snd_soc_component_set_jack(component, jack, NULL);
 176 
 177         if (ret) {
 178                 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
 179                 return ret;
 180         }
 181 
 182         return ret;
 183 };
 184 
 185 static int geminilake_rt5682_hw_params(struct snd_pcm_substream *substream,
 186         struct snd_pcm_hw_params *params)
 187 {
 188         struct snd_soc_pcm_runtime *rtd = substream->private_data;
 189         struct snd_soc_dai *codec_dai = rtd->codec_dai;
 190         int ret;
 191 
 192         /* Set valid bitmask & configuration for I2S in 24 bit */
 193         ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2, 24);
 194         if (ret < 0) {
 195                 dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
 196                 return ret;
 197         }
 198 
 199         return ret;
 200 }
 201 
 202 static struct snd_soc_ops geminilake_rt5682_ops = {
 203         .hw_params = geminilake_rt5682_hw_params,
 204 };
 205 
 206 static int geminilake_hdmi_init(struct snd_soc_pcm_runtime *rtd)
 207 {
 208         struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 209         struct snd_soc_dai *dai = rtd->codec_dai;
 210         struct glk_hdmi_pcm *pcm;
 211 
 212         pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
 213         if (!pcm)
 214                 return -ENOMEM;
 215 
 216         pcm->device = GLK_DPCM_AUDIO_HDMI1_PB + dai->id;
 217         pcm->codec_dai = dai;
 218 
 219         list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
 220 
 221         return 0;
 222 }
 223 
 224 static int geminilake_rt5682_fe_init(struct snd_soc_pcm_runtime *rtd)
 225 {
 226         struct snd_soc_component *component = rtd->cpu_dai->component;
 227         struct snd_soc_dapm_context *dapm;
 228         int ret;
 229 
 230         dapm = snd_soc_component_get_dapm(component);
 231         ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
 232         if (ret) {
 233                 dev_err(rtd->dev, "Ref Cap ignore suspend failed %d\n", ret);
 234                 return ret;
 235         }
 236 
 237         return ret;
 238 }
 239 
 240 static const unsigned int rates[] = {
 241         48000,
 242 };
 243 
 244 static const struct snd_pcm_hw_constraint_list constraints_rates = {
 245         .count = ARRAY_SIZE(rates),
 246         .list  = rates,
 247         .mask = 0,
 248 };
 249 
 250 static const unsigned int channels[] = {
 251         DUAL_CHANNEL,
 252 };
 253 
 254 static const struct snd_pcm_hw_constraint_list constraints_channels = {
 255         .count = ARRAY_SIZE(channels),
 256         .list = channels,
 257         .mask = 0,
 258 };
 259 
 260 static unsigned int channels_quad[] = {
 261         QUAD_CHANNEL,
 262 };
 263 
 264 static struct snd_pcm_hw_constraint_list constraints_channels_quad = {
 265         .count = ARRAY_SIZE(channels_quad),
 266         .list = channels_quad,
 267         .mask = 0,
 268 };
 269 
 270 static int geminilake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
 271                 struct snd_pcm_hw_params *params)
 272 {
 273         struct snd_interval *channels = hw_param_interval(params,
 274                                 SNDRV_PCM_HW_PARAM_CHANNELS);
 275 
 276         /*
 277          * set BE channel constraint as user FE channels
 278          */
 279         channels->min = channels->max = 4;
 280 
 281         return 0;
 282 }
 283 
 284 static int geminilake_dmic_startup(struct snd_pcm_substream *substream)
 285 {
 286         struct snd_pcm_runtime *runtime = substream->runtime;
 287 
 288         runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
 289         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 290                         &constraints_channels_quad);
 291 
 292         return snd_pcm_hw_constraint_list(substream->runtime, 0,
 293                         SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
 294 }
 295 
 296 static const struct snd_soc_ops geminilake_dmic_ops = {
 297         .startup = geminilake_dmic_startup,
 298 };
 299 
 300 static const unsigned int rates_16000[] = {
 301         16000,
 302 };
 303 
 304 static const struct snd_pcm_hw_constraint_list constraints_16000 = {
 305         .count = ARRAY_SIZE(rates_16000),
 306         .list  = rates_16000,
 307 };
 308 
 309 static int geminilake_refcap_startup(struct snd_pcm_substream *substream)
 310 {
 311         return snd_pcm_hw_constraint_list(substream->runtime, 0,
 312                                 SNDRV_PCM_HW_PARAM_RATE,
 313                                 &constraints_16000);
 314 };
 315 
 316 static const struct snd_soc_ops geminilake_refcap_ops = {
 317         .startup = geminilake_refcap_startup,
 318 };
 319 
 320 SND_SOC_DAILINK_DEF(dummy,
 321         DAILINK_COMP_ARRAY(COMP_DUMMY()));
 322 
 323 SND_SOC_DAILINK_DEF(system,
 324         DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
 325 
 326 SND_SOC_DAILINK_DEF(system2,
 327         DAILINK_COMP_ARRAY(COMP_CPU("System Pin2")));
 328 
 329 SND_SOC_DAILINK_DEF(echoref,
 330         DAILINK_COMP_ARRAY(COMP_CPU("Echoref 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(ssp1_pin,
 348         DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
 349 SND_SOC_DAILINK_DEF(ssp1_codec,
 350         DAILINK_COMP_ARRAY(COMP_CODEC(MAXIM_DEV0_NAME,
 351                                       GLK_MAXIM_CODEC_DAI)));
 352 
 353 SND_SOC_DAILINK_DEF(ssp2_pin,
 354         DAILINK_COMP_ARRAY(COMP_CPU("SSP2 Pin")));
 355 SND_SOC_DAILINK_DEF(ssp2_codec,
 356         DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00",
 357                                       GLK_REALTEK_CODEC_DAI)));
 358 
 359 SND_SOC_DAILINK_DEF(dmic_pin,
 360         DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
 361 SND_SOC_DAILINK_DEF(dmic_codec,
 362         DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
 363 
 364 SND_SOC_DAILINK_DEF(idisp1_pin,
 365         DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
 366 SND_SOC_DAILINK_DEF(idisp1_codec,
 367         DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "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", "intel-hdmi-hifi2")));
 373 
 374 SND_SOC_DAILINK_DEF(idisp3_pin,
 375         DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
 376 SND_SOC_DAILINK_DEF(idisp3_codec,
 377         DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3")));
 378 
 379 SND_SOC_DAILINK_DEF(platform,
 380         DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0")));
 381 
 382 /* geminilake digital audio interface glue - connects codec <--> CPU */
 383 static struct snd_soc_dai_link geminilake_dais[] = {
 384         /* Front End DAI links */
 385         [GLK_DPCM_AUDIO_PB] = {
 386                 .name = "Glk Audio Port",
 387                 .stream_name = "Audio",
 388                 .dynamic = 1,
 389                 .nonatomic = 1,
 390                 .init = geminilake_rt5682_fe_init,
 391                 .trigger = {
 392                         SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 393                 .dpcm_playback = 1,
 394                 SND_SOC_DAILINK_REG(system, dummy, platform),
 395         },
 396         [GLK_DPCM_AUDIO_CP] = {
 397                 .name = "Glk Audio Capture Port",
 398                 .stream_name = "Audio Record",
 399                 .dynamic = 1,
 400                 .nonatomic = 1,
 401                 .trigger = {
 402                         SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 403                 .dpcm_capture = 1,
 404                 SND_SOC_DAILINK_REG(system, dummy, platform),
 405         },
 406         [GLK_DPCM_AUDIO_HS_PB] = {
 407                 .name = "Glk Audio Headset Playback",
 408                 .stream_name = "Headset Audio",
 409                 .dpcm_playback = 1,
 410                 .nonatomic = 1,
 411                 .dynamic = 1,
 412                 SND_SOC_DAILINK_REG(system2, dummy, platform),
 413         },
 414         [GLK_DPCM_AUDIO_ECHO_REF_CP] = {
 415                 .name = "Glk Audio Echo Reference cap",
 416                 .stream_name = "Echoreference Capture",
 417                 .init = NULL,
 418                 .capture_only = 1,
 419                 .nonatomic = 1,
 420                 SND_SOC_DAILINK_REG(echoref, dummy, platform),
 421         },
 422         [GLK_DPCM_AUDIO_REF_CP] = {
 423                 .name = "Glk Audio Reference cap",
 424                 .stream_name = "Refcap",
 425                 .init = NULL,
 426                 .dpcm_capture = 1,
 427                 .nonatomic = 1,
 428                 .dynamic = 1,
 429                 .ops = &geminilake_refcap_ops,
 430                 SND_SOC_DAILINK_REG(reference, dummy, platform),
 431         },
 432         [GLK_DPCM_AUDIO_DMIC_CP] = {
 433                 .name = "Glk Audio DMIC cap",
 434                 .stream_name = "dmiccap",
 435                 .init = NULL,
 436                 .dpcm_capture = 1,
 437                 .nonatomic = 1,
 438                 .dynamic = 1,
 439                 .ops = &geminilake_dmic_ops,
 440                 SND_SOC_DAILINK_REG(dmic, dummy, platform),
 441         },
 442         [GLK_DPCM_AUDIO_HDMI1_PB] = {
 443                 .name = "Glk HDMI Port1",
 444                 .stream_name = "Hdmi1",
 445                 .dpcm_playback = 1,
 446                 .init = NULL,
 447                 .trigger = {
 448                         SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 449                 .nonatomic = 1,
 450                 .dynamic = 1,
 451                 SND_SOC_DAILINK_REG(hdmi1, dummy, platform),
 452         },
 453         [GLK_DPCM_AUDIO_HDMI2_PB] =     {
 454                 .name = "Glk HDMI Port2",
 455                 .stream_name = "Hdmi2",
 456                 .dpcm_playback = 1,
 457                 .init = NULL,
 458                 .trigger = {
 459                         SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 460                 .nonatomic = 1,
 461                 .dynamic = 1,
 462                 SND_SOC_DAILINK_REG(hdmi2, dummy, platform),
 463         },
 464         [GLK_DPCM_AUDIO_HDMI3_PB] =     {
 465                 .name = "Glk HDMI Port3",
 466                 .stream_name = "Hdmi3",
 467                 .trigger = {
 468                         SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 469                 .dpcm_playback = 1,
 470                 .init = NULL,
 471                 .nonatomic = 1,
 472                 .dynamic = 1,
 473                 SND_SOC_DAILINK_REG(hdmi3, dummy, platform),
 474         },
 475         /* Back End DAI links */
 476         {
 477                 /* SSP1 - Codec */
 478                 .name = "SSP1-Codec",
 479                 .id = 0,
 480                 .no_pcm = 1,
 481                 .dai_fmt = SND_SOC_DAIFMT_I2S |
 482                         SND_SOC_DAIFMT_NB_NF |
 483                         SND_SOC_DAIFMT_CBS_CFS,
 484                 .ignore_pmdown_time = 1,
 485                 .be_hw_params_fixup = geminilake_ssp_fixup,
 486                 .dpcm_playback = 1,
 487                 SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
 488         },
 489         {
 490                 /* SSP2 - Codec */
 491                 .name = "SSP2-Codec",
 492                 .id = 1,
 493                 .no_pcm = 1,
 494                 .init = geminilake_rt5682_codec_init,
 495                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 496                         SND_SOC_DAIFMT_CBS_CFS,
 497                 .ignore_pmdown_time = 1,
 498                 .be_hw_params_fixup = geminilake_ssp_fixup,
 499                 .ops = &geminilake_rt5682_ops,
 500                 .dpcm_playback = 1,
 501                 .dpcm_capture = 1,
 502                 SND_SOC_DAILINK_REG(ssp2_pin, ssp2_codec, platform),
 503         },
 504         {
 505                 .name = "dmic01",
 506                 .id = 2,
 507                 .ignore_suspend = 1,
 508                 .be_hw_params_fixup = geminilake_dmic_fixup,
 509                 .dpcm_capture = 1,
 510                 .no_pcm = 1,
 511                 SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
 512         },
 513         {
 514                 .name = "iDisp1",
 515                 .id = 3,
 516                 .init = geminilake_hdmi_init,
 517                 .dpcm_playback = 1,
 518                 .no_pcm = 1,
 519                 SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
 520         },
 521         {
 522                 .name = "iDisp2",
 523                 .id = 4,
 524                 .init = geminilake_hdmi_init,
 525                 .dpcm_playback = 1,
 526                 .no_pcm = 1,
 527                 SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
 528         },
 529         {
 530                 .name = "iDisp3",
 531                 .id = 5,
 532                 .init = geminilake_hdmi_init,
 533                 .dpcm_playback = 1,
 534                 .no_pcm = 1,
 535                 SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
 536         },
 537 };
 538 
 539 static int glk_card_late_probe(struct snd_soc_card *card)
 540 {
 541         struct glk_card_private *ctx = snd_soc_card_get_drvdata(card);
 542         struct snd_soc_component *component = NULL;
 543         char jack_name[NAME_SIZE];
 544         struct glk_hdmi_pcm *pcm;
 545         int err = 0;
 546         int i = 0;
 547 
 548         list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 549                 component = pcm->codec_dai->component;
 550                 snprintf(jack_name, sizeof(jack_name),
 551                         "HDMI/DP, pcm=%d Jack", pcm->device);
 552                 err = snd_soc_card_jack_new(card, jack_name,
 553                                         SND_JACK_AVOUT, &geminilake_hdmi[i],
 554                                         NULL, 0);
 555 
 556                 if (err)
 557                         return err;
 558 
 559                 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 560                                                 &geminilake_hdmi[i]);
 561                 if (err < 0)
 562                         return err;
 563 
 564                 i++;
 565         }
 566 
 567         if (!component)
 568                 return -EINVAL;
 569 
 570         return hdac_hdmi_jack_port_init(component, &card->dapm);
 571 }
 572 
 573 /* geminilake audio machine driver for SPT + RT5682 */
 574 static struct snd_soc_card glk_audio_card_rt5682_m98357a = {
 575         .name = "glkrt5682max",
 576         .owner = THIS_MODULE,
 577         .dai_link = geminilake_dais,
 578         .num_links = ARRAY_SIZE(geminilake_dais),
 579         .controls = geminilake_controls,
 580         .num_controls = ARRAY_SIZE(geminilake_controls),
 581         .dapm_widgets = geminilake_widgets,
 582         .num_dapm_widgets = ARRAY_SIZE(geminilake_widgets),
 583         .dapm_routes = geminilake_map,
 584         .num_dapm_routes = ARRAY_SIZE(geminilake_map),
 585         .fully_routed = true,
 586         .late_probe = glk_card_late_probe,
 587 };
 588 
 589 static int geminilake_audio_probe(struct platform_device *pdev)
 590 {
 591         struct glk_card_private *ctx;
 592         struct snd_soc_acpi_mach *mach;
 593         const char *platform_name;
 594         struct snd_soc_card *card;
 595         int ret;
 596 
 597         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
 598         if (!ctx)
 599                 return -ENOMEM;
 600 
 601         INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
 602 
 603         card = &glk_audio_card_rt5682_m98357a;
 604         card->dev = &pdev->dev;
 605         snd_soc_card_set_drvdata(card, ctx);
 606 
 607         /* override plaform name, if required */
 608         mach = (&pdev->dev)->platform_data;
 609         platform_name = mach->mach_params.platform;
 610 
 611         ret = snd_soc_fixup_dai_links_platform_name(card, platform_name);
 612         if (ret)
 613                 return ret;
 614 
 615         return devm_snd_soc_register_card(&pdev->dev, card);
 616 }
 617 
 618 static const struct platform_device_id glk_board_ids[] = {
 619         {
 620                 .name = "glk_rt5682_max98357a",
 621                 .driver_data =
 622                         (kernel_ulong_t)&glk_audio_card_rt5682_m98357a,
 623         },
 624         { }
 625 };
 626 
 627 static struct platform_driver geminilake_audio = {
 628         .probe = geminilake_audio_probe,
 629         .driver = {
 630                 .name = "glk_rt5682_max98357a",
 631                 .pm = &snd_soc_pm_ops,
 632         },
 633         .id_table = glk_board_ids,
 634 };
 635 module_platform_driver(geminilake_audio)
 636 
 637 /* Module information */
 638 MODULE_DESCRIPTION("Geminilake Audio Machine driver-RT5682 & MAX98357A in I2S mode");
 639 MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
 640 MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
 641 MODULE_LICENSE("GPL v2");
 642 MODULE_ALIAS("platform:glk_rt5682_max98357a");

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