1a86d5057SHarsha Priya /* 2a86d5057SHarsha Priya * Intel Skylake I2S Machine Driver for NAU88L25+SSM4567 3a86d5057SHarsha Priya * 4a86d5057SHarsha Priya * Copyright (C) 2015, Intel Corporation. All rights reserved. 5a86d5057SHarsha Priya * 6a86d5057SHarsha Priya * Modified from: 7a86d5057SHarsha Priya * Intel Skylake I2S Machine Driver for NAU88L25 and SSM4567 8a86d5057SHarsha Priya * 9a86d5057SHarsha Priya * Copyright (C) 2015, Intel Corporation. All rights reserved. 10a86d5057SHarsha Priya * 11a86d5057SHarsha Priya * This program is free software; you can redistribute it and/or 12a86d5057SHarsha Priya * modify it under the terms of the GNU General Public License version 13a86d5057SHarsha Priya * 2 as published by the Free Software Foundation. 14a86d5057SHarsha Priya * 15a86d5057SHarsha Priya * This program is distributed in the hope that it will be useful, 16a86d5057SHarsha Priya * but WITHOUT ANY WARRANTY; without even the implied warranty of 17a86d5057SHarsha Priya * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18a86d5057SHarsha Priya * GNU General Public License for more details. 19a86d5057SHarsha Priya */ 20a86d5057SHarsha Priya 21a86d5057SHarsha Priya #include <linux/module.h> 22a86d5057SHarsha Priya #include <linux/platform_device.h> 23a86d5057SHarsha Priya #include <sound/core.h> 24a86d5057SHarsha Priya #include <sound/pcm.h> 25a86d5057SHarsha Priya #include <sound/soc.h> 26a86d5057SHarsha Priya #include <sound/jack.h> 27a86d5057SHarsha Priya #include <sound/pcm_params.h> 28a86d5057SHarsha Priya #include "../../codecs/nau8825.h" 29bc5f6ac9SJeeja KP #include "../../codecs/hdac_hdmi.h" 30a86d5057SHarsha Priya 31a86d5057SHarsha Priya #define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" 32a86d5057SHarsha Priya #define SKL_SSM_CODEC_DAI "ssm4567-hifi" 33a86d5057SHarsha Priya 34a86d5057SHarsha Priya static struct snd_soc_jack skylake_headset; 35a86d5057SHarsha Priya static struct snd_soc_card skylake_audio_card; 36a86d5057SHarsha Priya 3746ed1a27SSubhransu S. Prusty struct skl_hdmi_pcm { 3846ed1a27SSubhransu S. Prusty struct list_head head; 3946ed1a27SSubhransu S. Prusty struct snd_soc_dai *codec_dai; 4046ed1a27SSubhransu S. Prusty int device; 4146ed1a27SSubhransu S. Prusty }; 4246ed1a27SSubhransu S. Prusty 4346ed1a27SSubhransu S. Prusty struct skl_nau88125_private { 4446ed1a27SSubhransu S. Prusty struct list_head hdmi_pcm_list; 4546ed1a27SSubhransu S. Prusty }; 46bc5f6ac9SJeeja KP enum { 47bc5f6ac9SJeeja KP SKL_DPCM_AUDIO_PB = 0, 48bc5f6ac9SJeeja KP SKL_DPCM_AUDIO_CP, 49bc5f6ac9SJeeja KP SKL_DPCM_AUDIO_REF_CP, 50bc5f6ac9SJeeja KP SKL_DPCM_AUDIO_DMIC_CP, 51bc5f6ac9SJeeja KP SKL_DPCM_AUDIO_HDMI1_PB, 52bc5f6ac9SJeeja KP SKL_DPCM_AUDIO_HDMI2_PB, 53bc5f6ac9SJeeja KP SKL_DPCM_AUDIO_HDMI3_PB, 54bc5f6ac9SJeeja KP }; 55bc5f6ac9SJeeja KP 56a86d5057SHarsha Priya static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card) 57a86d5057SHarsha Priya { 58a86d5057SHarsha Priya struct snd_soc_pcm_runtime *rtd; 59a86d5057SHarsha Priya 6085af2a66SVinod Koul list_for_each_entry(rtd, &card->rtd_list, list) { 6185af2a66SVinod Koul 62a86d5057SHarsha Priya if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI, 63a86d5057SHarsha Priya strlen(SKL_NUVOTON_CODEC_DAI))) 64a86d5057SHarsha Priya return rtd->codec_dai; 65a86d5057SHarsha Priya } 66a86d5057SHarsha Priya 67a86d5057SHarsha Priya return NULL; 68a86d5057SHarsha Priya } 69a86d5057SHarsha Priya 70a86d5057SHarsha Priya static const struct snd_kcontrol_new skylake_controls[] = { 71a86d5057SHarsha Priya SOC_DAPM_PIN_SWITCH("Headphone Jack"), 72a86d5057SHarsha Priya SOC_DAPM_PIN_SWITCH("Headset Mic"), 73a86d5057SHarsha Priya SOC_DAPM_PIN_SWITCH("Left Speaker"), 74a86d5057SHarsha Priya SOC_DAPM_PIN_SWITCH("Right Speaker"), 75a86d5057SHarsha Priya }; 76a86d5057SHarsha Priya 77a86d5057SHarsha Priya static int platform_clock_control(struct snd_soc_dapm_widget *w, 78a86d5057SHarsha Priya struct snd_kcontrol *k, int event) 79a86d5057SHarsha Priya { 80a86d5057SHarsha Priya struct snd_soc_dapm_context *dapm = w->dapm; 81a86d5057SHarsha Priya struct snd_soc_card *card = dapm->card; 82a86d5057SHarsha Priya struct snd_soc_dai *codec_dai; 83a86d5057SHarsha Priya int ret; 84a86d5057SHarsha Priya 85a86d5057SHarsha Priya codec_dai = skl_get_codec_dai(card); 86a86d5057SHarsha Priya if (!codec_dai) { 87a86d5057SHarsha Priya dev_err(card->dev, "Codec dai not found\n"); 88a86d5057SHarsha Priya return -EIO; 89a86d5057SHarsha Priya } 90a86d5057SHarsha Priya 91a86d5057SHarsha Priya if (SND_SOC_DAPM_EVENT_ON(event)) { 92a86d5057SHarsha Priya ret = snd_soc_dai_set_sysclk(codec_dai, 93a86d5057SHarsha Priya NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN); 94a86d5057SHarsha Priya if (ret < 0) { 95a86d5057SHarsha Priya dev_err(card->dev, "set sysclk err = %d\n", ret); 96a86d5057SHarsha Priya return -EIO; 97a86d5057SHarsha Priya } 98a86d5057SHarsha Priya } else { 99a86d5057SHarsha Priya ret = snd_soc_dai_set_sysclk(codec_dai, 100a86d5057SHarsha Priya NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN); 101a86d5057SHarsha Priya if (ret < 0) { 102a86d5057SHarsha Priya dev_err(card->dev, "set sysclk err = %d\n", ret); 103a86d5057SHarsha Priya return -EIO; 104a86d5057SHarsha Priya } 105a86d5057SHarsha Priya } 106a86d5057SHarsha Priya return ret; 107a86d5057SHarsha Priya } 108a86d5057SHarsha Priya 109a86d5057SHarsha Priya static const struct snd_soc_dapm_widget skylake_widgets[] = { 110a86d5057SHarsha Priya SND_SOC_DAPM_HP("Headphone Jack", NULL), 111a86d5057SHarsha Priya SND_SOC_DAPM_MIC("Headset Mic", NULL), 112a86d5057SHarsha Priya SND_SOC_DAPM_SPK("Left Speaker", NULL), 113a86d5057SHarsha Priya SND_SOC_DAPM_SPK("Right Speaker", NULL), 114a86d5057SHarsha Priya SND_SOC_DAPM_MIC("SoC DMIC", NULL), 115743ad80eSFang, Yang A SND_SOC_DAPM_SPK("DP", NULL), 116743ad80eSFang, Yang A SND_SOC_DAPM_SPK("HDMI", NULL), 117a86d5057SHarsha Priya SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, 118a86d5057SHarsha Priya platform_clock_control, SND_SOC_DAPM_PRE_PMU | 119a86d5057SHarsha Priya SND_SOC_DAPM_POST_PMD), 120a86d5057SHarsha Priya }; 121a86d5057SHarsha Priya 122a86d5057SHarsha Priya static const struct snd_soc_dapm_route skylake_map[] = { 123a86d5057SHarsha Priya /* HP jack connectors - unknown if we have jack detection */ 124a86d5057SHarsha Priya {"Headphone Jack", NULL, "HPOL"}, 125a86d5057SHarsha Priya {"Headphone Jack", NULL, "HPOR"}, 126a86d5057SHarsha Priya 127a86d5057SHarsha Priya /* speaker */ 128a86d5057SHarsha Priya {"Left Speaker", NULL, "Left OUT"}, 129a86d5057SHarsha Priya {"Right Speaker", NULL, "Right OUT"}, 130a86d5057SHarsha Priya 131a86d5057SHarsha Priya /* other jacks */ 132a86d5057SHarsha Priya {"MIC", NULL, "Headset Mic"}, 1334c6ebc3eSFang, Yang A {"DMic", NULL, "SoC DMIC"}, 134a86d5057SHarsha Priya 135743ad80eSFang, Yang A {"HDMI", NULL, "hif5 Output"}, 136743ad80eSFang, Yang A {"DP", NULL, "hif6 Output"}, 137a86d5057SHarsha Priya /* CODEC BE connections */ 138a86d5057SHarsha Priya { "Left Playback", NULL, "ssp0 Tx"}, 139a86d5057SHarsha Priya { "Right Playback", NULL, "ssp0 Tx"}, 140a86d5057SHarsha Priya { "ssp0 Tx", NULL, "codec0_out"}, 141a86d5057SHarsha Priya 1425093f928SSathya Prakash M R /* IV feedback path */ 1435093f928SSathya Prakash M R { "codec0_lp_in", NULL, "ssp0 Rx"}, 1445188b95aSJeeja KP { "ssp0 Rx", NULL, "Left Capture Sense" }, 1455188b95aSJeeja KP { "ssp0 Rx", NULL, "Right Capture Sense" }, 1465093f928SSathya Prakash M R 1474c6ebc3eSFang, Yang A { "Playback", NULL, "ssp1 Tx"}, 148a86d5057SHarsha Priya { "ssp1 Tx", NULL, "codec1_out"}, 149a86d5057SHarsha Priya 150a86d5057SHarsha Priya { "codec0_in", NULL, "ssp1 Rx" }, 1514c6ebc3eSFang, Yang A { "ssp1 Rx", NULL, "Capture" }, 152a86d5057SHarsha Priya 153a86d5057SHarsha Priya /* DMIC */ 154a86d5057SHarsha Priya { "dmic01_hifi", NULL, "DMIC01 Rx" }, 1554c6ebc3eSFang, Yang A { "DMIC01 Rx", NULL, "DMIC AIF" }, 156bc5f6ac9SJeeja KP 157bc5f6ac9SJeeja KP { "hifi3", NULL, "iDisp3 Tx"}, 158bc5f6ac9SJeeja KP { "iDisp3 Tx", NULL, "iDisp3_out"}, 159bc5f6ac9SJeeja KP { "hifi2", NULL, "iDisp2 Tx"}, 160bc5f6ac9SJeeja KP { "iDisp2 Tx", NULL, "iDisp2_out"}, 161bc5f6ac9SJeeja KP { "hifi1", NULL, "iDisp1 Tx"}, 162bc5f6ac9SJeeja KP { "iDisp1 Tx", NULL, "iDisp1_out"}, 163bc5f6ac9SJeeja KP 164a86d5057SHarsha Priya { "Headphone Jack", NULL, "Platform Clock" }, 165a86d5057SHarsha Priya { "Headset Mic", NULL, "Platform Clock" }, 166a86d5057SHarsha Priya }; 167a86d5057SHarsha Priya 168a86d5057SHarsha Priya static struct snd_soc_codec_conf ssm4567_codec_conf[] = { 169a86d5057SHarsha Priya { 170a86d5057SHarsha Priya .dev_name = "i2c-INT343B:00", 171a86d5057SHarsha Priya .name_prefix = "Left", 172a86d5057SHarsha Priya }, 173a86d5057SHarsha Priya { 174a86d5057SHarsha Priya .dev_name = "i2c-INT343B:01", 175a86d5057SHarsha Priya .name_prefix = "Right", 176a86d5057SHarsha Priya }, 177a86d5057SHarsha Priya }; 178a86d5057SHarsha Priya 179a86d5057SHarsha Priya static struct snd_soc_dai_link_component ssm4567_codec_components[] = { 180a86d5057SHarsha Priya { /* Left */ 181a86d5057SHarsha Priya .name = "i2c-INT343B:00", 182a86d5057SHarsha Priya .dai_name = SKL_SSM_CODEC_DAI, 183a86d5057SHarsha Priya }, 184a86d5057SHarsha Priya { /* Right */ 185a86d5057SHarsha Priya .name = "i2c-INT343B:01", 186a86d5057SHarsha Priya .dai_name = SKL_SSM_CODEC_DAI, 187a86d5057SHarsha Priya }, 188a86d5057SHarsha Priya }; 189a86d5057SHarsha Priya 190a86d5057SHarsha Priya static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd) 191a86d5057SHarsha Priya { 192a86d5057SHarsha Priya int ret; 193a86d5057SHarsha Priya 194a86d5057SHarsha Priya /* Slot 1 for left */ 195a86d5057SHarsha Priya ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[0], 0x01, 0x01, 2, 48); 196a86d5057SHarsha Priya if (ret < 0) 197a86d5057SHarsha Priya return ret; 198a86d5057SHarsha Priya 199a86d5057SHarsha Priya /* Slot 2 for right */ 200a86d5057SHarsha Priya ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[1], 0x02, 0x02, 2, 48); 201a86d5057SHarsha Priya if (ret < 0) 202a86d5057SHarsha Priya return ret; 203a86d5057SHarsha Priya 204a86d5057SHarsha Priya return ret; 205a86d5057SHarsha Priya } 206a86d5057SHarsha Priya 207a86d5057SHarsha Priya static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) 208a86d5057SHarsha Priya { 209a86d5057SHarsha Priya int ret; 210a86d5057SHarsha Priya struct snd_soc_codec *codec = rtd->codec; 211a86d5057SHarsha Priya 212a86d5057SHarsha Priya /* 213a86d5057SHarsha Priya * 4 buttons here map to the google Reference headset 214a86d5057SHarsha Priya * The use of these buttons can be decided by the user space. 215a86d5057SHarsha Priya */ 216a86d5057SHarsha Priya ret = snd_soc_card_jack_new(&skylake_audio_card, "Headset Jack", 217a86d5057SHarsha Priya SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | 218a86d5057SHarsha Priya SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset, 219a86d5057SHarsha Priya NULL, 0); 220a86d5057SHarsha Priya if (ret) { 221a86d5057SHarsha Priya dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); 222a86d5057SHarsha Priya return ret; 223a86d5057SHarsha Priya } 224a86d5057SHarsha Priya 225a86d5057SHarsha Priya nau8825_enable_jack_detect(codec, &skylake_headset); 226a86d5057SHarsha Priya 227941eee74SYong Zhi snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); 228941eee74SYong Zhi 229a86d5057SHarsha Priya return ret; 230a86d5057SHarsha Priya } 231a86d5057SHarsha Priya 232bc5f6ac9SJeeja KP static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) 233bc5f6ac9SJeeja KP { 23446ed1a27SSubhransu S. Prusty struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 235bc5f6ac9SJeeja KP struct snd_soc_dai *dai = rtd->codec_dai; 23646ed1a27SSubhransu S. Prusty struct skl_hdmi_pcm *pcm; 237bc5f6ac9SJeeja KP 23846ed1a27SSubhransu S. Prusty pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 23946ed1a27SSubhransu S. Prusty if (!pcm) 24046ed1a27SSubhransu S. Prusty return -ENOMEM; 24146ed1a27SSubhransu S. Prusty 24246ed1a27SSubhransu S. Prusty pcm->device = SKL_DPCM_AUDIO_HDMI1_PB; 24346ed1a27SSubhransu S. Prusty pcm->codec_dai = dai; 24446ed1a27SSubhransu S. Prusty 24546ed1a27SSubhransu S. Prusty list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 24646ed1a27SSubhransu S. Prusty 24746ed1a27SSubhransu S. Prusty return 0; 248bc5f6ac9SJeeja KP } 249bc5f6ac9SJeeja KP 250bc5f6ac9SJeeja KP static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) 251bc5f6ac9SJeeja KP { 25246ed1a27SSubhransu S. Prusty struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 253bc5f6ac9SJeeja KP struct snd_soc_dai *dai = rtd->codec_dai; 25446ed1a27SSubhransu S. Prusty struct skl_hdmi_pcm *pcm; 255bc5f6ac9SJeeja KP 25646ed1a27SSubhransu S. Prusty pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 25746ed1a27SSubhransu S. Prusty if (!pcm) 25846ed1a27SSubhransu S. Prusty return -ENOMEM; 25946ed1a27SSubhransu S. Prusty 26046ed1a27SSubhransu S. Prusty pcm->device = SKL_DPCM_AUDIO_HDMI2_PB; 26146ed1a27SSubhransu S. Prusty pcm->codec_dai = dai; 26246ed1a27SSubhransu S. Prusty 26346ed1a27SSubhransu S. Prusty list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 26446ed1a27SSubhransu S. Prusty 26546ed1a27SSubhransu S. Prusty return 0; 266bc5f6ac9SJeeja KP } 267bc5f6ac9SJeeja KP 268bc5f6ac9SJeeja KP 269bc5f6ac9SJeeja KP static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) 270bc5f6ac9SJeeja KP { 27146ed1a27SSubhransu S. Prusty struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 272bc5f6ac9SJeeja KP struct snd_soc_dai *dai = rtd->codec_dai; 27346ed1a27SSubhransu S. Prusty struct skl_hdmi_pcm *pcm; 274bc5f6ac9SJeeja KP 27546ed1a27SSubhransu S. Prusty pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 27646ed1a27SSubhransu S. Prusty if (!pcm) 27746ed1a27SSubhransu S. Prusty return -ENOMEM; 27846ed1a27SSubhransu S. Prusty 27946ed1a27SSubhransu S. Prusty pcm->device = SKL_DPCM_AUDIO_HDMI3_PB; 28046ed1a27SSubhransu S. Prusty pcm->codec_dai = dai; 28146ed1a27SSubhransu S. Prusty 28246ed1a27SSubhransu S. Prusty list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 28346ed1a27SSubhransu S. Prusty 28446ed1a27SSubhransu S. Prusty return 0; 285bc5f6ac9SJeeja KP } 286bc5f6ac9SJeeja KP 2872616e27eSYong Zhi static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) 2882616e27eSYong Zhi { 2892616e27eSYong Zhi struct snd_soc_dapm_context *dapm; 2902616e27eSYong Zhi struct snd_soc_component *component = rtd->cpu_dai->component; 2912616e27eSYong Zhi 2922616e27eSYong Zhi dapm = snd_soc_component_get_dapm(component); 2932616e27eSYong Zhi snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); 2942616e27eSYong Zhi 2952616e27eSYong Zhi return 0; 2962616e27eSYong Zhi } 2972616e27eSYong Zhi 2982616e27eSYong Zhi static unsigned int rates[] = { 2992616e27eSYong Zhi 48000, 3002616e27eSYong Zhi }; 3012616e27eSYong Zhi 3022616e27eSYong Zhi static struct snd_pcm_hw_constraint_list constraints_rates = { 3032616e27eSYong Zhi .count = ARRAY_SIZE(rates), 3042616e27eSYong Zhi .list = rates, 3052616e27eSYong Zhi .mask = 0, 3062616e27eSYong Zhi }; 3072616e27eSYong Zhi 3082616e27eSYong Zhi static unsigned int channels[] = { 3092616e27eSYong Zhi 2, 3102616e27eSYong Zhi }; 3112616e27eSYong Zhi 3122616e27eSYong Zhi static struct snd_pcm_hw_constraint_list constraints_channels = { 3132616e27eSYong Zhi .count = ARRAY_SIZE(channels), 3142616e27eSYong Zhi .list = channels, 3152616e27eSYong Zhi .mask = 0, 3162616e27eSYong Zhi }; 3172616e27eSYong Zhi 3182616e27eSYong Zhi static int skl_fe_startup(struct snd_pcm_substream *substream) 3192616e27eSYong Zhi { 3202616e27eSYong Zhi struct snd_pcm_runtime *runtime = substream->runtime; 3212616e27eSYong Zhi 3222616e27eSYong Zhi /* 3232616e27eSYong Zhi * on this platform for PCM device we support, 3242616e27eSYong Zhi * 48Khz 3252616e27eSYong Zhi * stereo 3262616e27eSYong Zhi * 16 bit audio 3272616e27eSYong Zhi */ 3282616e27eSYong Zhi 3292616e27eSYong Zhi runtime->hw.channels_max = 2; 3302616e27eSYong Zhi snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 3312616e27eSYong Zhi &constraints_channels); 3322616e27eSYong Zhi 3332616e27eSYong Zhi runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 3342616e27eSYong Zhi snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 3352616e27eSYong Zhi 3362616e27eSYong Zhi snd_pcm_hw_constraint_list(runtime, 0, 3372616e27eSYong Zhi SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 3382616e27eSYong Zhi 3392616e27eSYong Zhi return 0; 3402616e27eSYong Zhi } 3412616e27eSYong Zhi 3422616e27eSYong Zhi static const struct snd_soc_ops skylake_nau8825_fe_ops = { 3432616e27eSYong Zhi .startup = skl_fe_startup, 3442616e27eSYong Zhi }; 3452616e27eSYong Zhi 346a86d5057SHarsha Priya static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, 347a86d5057SHarsha Priya struct snd_pcm_hw_params *params) 348a86d5057SHarsha Priya { 349a86d5057SHarsha Priya struct snd_interval *rate = hw_param_interval(params, 350a86d5057SHarsha Priya SNDRV_PCM_HW_PARAM_RATE); 351a86d5057SHarsha Priya struct snd_interval *channels = hw_param_interval(params, 352a86d5057SHarsha Priya SNDRV_PCM_HW_PARAM_CHANNELS); 353a86d5057SHarsha Priya struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 354a86d5057SHarsha Priya 355a86d5057SHarsha Priya /* The ADSP will covert the FE rate to 48k, stereo */ 356a86d5057SHarsha Priya rate->min = rate->max = 48000; 357a86d5057SHarsha Priya channels->min = channels->max = 2; 358a86d5057SHarsha Priya 359a86d5057SHarsha Priya /* set SSP0 to 24 bit */ 360a86d5057SHarsha Priya snd_mask_none(fmt); 361a86d5057SHarsha Priya snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE); 362a86d5057SHarsha Priya return 0; 363a86d5057SHarsha Priya } 364a86d5057SHarsha Priya 3652616e27eSYong Zhi static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, 3662616e27eSYong Zhi struct snd_pcm_hw_params *params) 3672616e27eSYong Zhi { 3682616e27eSYong Zhi struct snd_interval *channels = hw_param_interval(params, 3692616e27eSYong Zhi SNDRV_PCM_HW_PARAM_CHANNELS); 3702616e27eSYong Zhi if (params_channels(params) == 2) 3712616e27eSYong Zhi channels->min = channels->max = 2; 3722616e27eSYong Zhi else 3732616e27eSYong Zhi channels->min = channels->max = 4; 3742616e27eSYong Zhi 3752616e27eSYong Zhi return 0; 3762616e27eSYong Zhi } 3772616e27eSYong Zhi 378a86d5057SHarsha Priya static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream, 379a86d5057SHarsha Priya struct snd_pcm_hw_params *params) 380a86d5057SHarsha Priya { 381a86d5057SHarsha Priya struct snd_soc_pcm_runtime *rtd = substream->private_data; 382a86d5057SHarsha Priya struct snd_soc_dai *codec_dai = rtd->codec_dai; 383a86d5057SHarsha Priya int ret; 384a86d5057SHarsha Priya 385a86d5057SHarsha Priya ret = snd_soc_dai_set_sysclk(codec_dai, 386a86d5057SHarsha Priya NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN); 387a86d5057SHarsha Priya 388a86d5057SHarsha Priya if (ret < 0) 389a86d5057SHarsha Priya dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); 390a86d5057SHarsha Priya 391a86d5057SHarsha Priya return ret; 392a86d5057SHarsha Priya } 393a86d5057SHarsha Priya 394a86d5057SHarsha Priya static struct snd_soc_ops skylake_nau8825_ops = { 395a86d5057SHarsha Priya .hw_params = skylake_nau8825_hw_params, 396a86d5057SHarsha Priya }; 397a86d5057SHarsha Priya 3982616e27eSYong Zhi static unsigned int channels_dmic[] = { 3992616e27eSYong Zhi 2, 4, 4002616e27eSYong Zhi }; 4012616e27eSYong Zhi 4022616e27eSYong Zhi static struct snd_pcm_hw_constraint_list constraints_dmic_channels = { 4032616e27eSYong Zhi .count = ARRAY_SIZE(channels_dmic), 4042616e27eSYong Zhi .list = channels_dmic, 4052616e27eSYong Zhi .mask = 0, 4062616e27eSYong Zhi }; 4072616e27eSYong Zhi 4082616e27eSYong Zhi static int skylake_dmic_startup(struct snd_pcm_substream *substream) 4092616e27eSYong Zhi { 4102616e27eSYong Zhi struct snd_pcm_runtime *runtime = substream->runtime; 4112616e27eSYong Zhi 4122616e27eSYong Zhi runtime->hw.channels_max = 4; 4132616e27eSYong Zhi snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 4142616e27eSYong Zhi &constraints_dmic_channels); 4152616e27eSYong Zhi 4162616e27eSYong Zhi return snd_pcm_hw_constraint_list(substream->runtime, 0, 4172616e27eSYong Zhi SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 4182616e27eSYong Zhi } 4192616e27eSYong Zhi 4202616e27eSYong Zhi static struct snd_soc_ops skylake_dmic_ops = { 4212616e27eSYong Zhi .startup = skylake_dmic_startup, 4222616e27eSYong Zhi }; 4232616e27eSYong Zhi 4242616e27eSYong Zhi static unsigned int rates_16000[] = { 4252616e27eSYong Zhi 16000, 4262616e27eSYong Zhi }; 4272616e27eSYong Zhi 4282616e27eSYong Zhi static struct snd_pcm_hw_constraint_list constraints_16000 = { 4292616e27eSYong Zhi .count = ARRAY_SIZE(rates_16000), 4302616e27eSYong Zhi .list = rates_16000, 4312616e27eSYong Zhi }; 4322616e27eSYong Zhi 4330c7941a6SYong Zhi static const unsigned int ch_mono[] = { 4340c7941a6SYong Zhi 1, 4350c7941a6SYong Zhi }; 4360c7941a6SYong Zhi 4370c7941a6SYong Zhi static const struct snd_pcm_hw_constraint_list constraints_refcap = { 4380c7941a6SYong Zhi .count = ARRAY_SIZE(ch_mono), 4390c7941a6SYong Zhi .list = ch_mono, 4400c7941a6SYong Zhi }; 4410c7941a6SYong Zhi 4422616e27eSYong Zhi static int skylake_refcap_startup(struct snd_pcm_substream *substream) 4432616e27eSYong Zhi { 4440c7941a6SYong Zhi substream->runtime->hw.channels_max = 1; 4450c7941a6SYong Zhi snd_pcm_hw_constraint_list(substream->runtime, 0, 4460c7941a6SYong Zhi SNDRV_PCM_HW_PARAM_CHANNELS, 4470c7941a6SYong Zhi &constraints_refcap); 4480c7941a6SYong Zhi 4492616e27eSYong Zhi return snd_pcm_hw_constraint_list(substream->runtime, 0, 4502616e27eSYong Zhi SNDRV_PCM_HW_PARAM_RATE, 4512616e27eSYong Zhi &constraints_16000); 4522616e27eSYong Zhi } 4532616e27eSYong Zhi 4542616e27eSYong Zhi static struct snd_soc_ops skylaye_refcap_ops = { 4552616e27eSYong Zhi .startup = skylake_refcap_startup, 4562616e27eSYong Zhi }; 4572616e27eSYong Zhi 458a86d5057SHarsha Priya /* skylake digital audio interface glue - connects codec <--> CPU */ 459a86d5057SHarsha Priya static struct snd_soc_dai_link skylake_dais[] = { 460a86d5057SHarsha Priya /* Front End DAI links */ 461bc5f6ac9SJeeja KP [SKL_DPCM_AUDIO_PB] = { 462a86d5057SHarsha Priya .name = "Skl Audio Port", 463a86d5057SHarsha Priya .stream_name = "Audio", 464a86d5057SHarsha Priya .cpu_dai_name = "System Pin", 465a86d5057SHarsha Priya .platform_name = "0000:00:1f.3", 466a86d5057SHarsha Priya .dynamic = 1, 467a86d5057SHarsha Priya .codec_name = "snd-soc-dummy", 468a86d5057SHarsha Priya .codec_dai_name = "snd-soc-dummy-dai", 469a86d5057SHarsha Priya .nonatomic = 1, 4702616e27eSYong Zhi .init = skylake_nau8825_fe_init, 471a86d5057SHarsha Priya .trigger = { 472a86d5057SHarsha Priya SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 473a86d5057SHarsha Priya .dpcm_playback = 1, 4742616e27eSYong Zhi .ops = &skylake_nau8825_fe_ops, 475a86d5057SHarsha Priya }, 476bc5f6ac9SJeeja KP [SKL_DPCM_AUDIO_CP] = { 477a86d5057SHarsha Priya .name = "Skl Audio Capture Port", 478a86d5057SHarsha Priya .stream_name = "Audio Record", 479a86d5057SHarsha Priya .cpu_dai_name = "System Pin", 480a86d5057SHarsha Priya .platform_name = "0000:00:1f.3", 481a86d5057SHarsha Priya .dynamic = 1, 482a86d5057SHarsha Priya .codec_name = "snd-soc-dummy", 483a86d5057SHarsha Priya .codec_dai_name = "snd-soc-dummy-dai", 484a86d5057SHarsha Priya .nonatomic = 1, 485a86d5057SHarsha Priya .trigger = { 486a86d5057SHarsha Priya SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 487a86d5057SHarsha Priya .dpcm_capture = 1, 4882616e27eSYong Zhi .ops = &skylake_nau8825_fe_ops, 489a86d5057SHarsha Priya }, 490bc5f6ac9SJeeja KP [SKL_DPCM_AUDIO_REF_CP] = { 491a86d5057SHarsha Priya .name = "Skl Audio Reference cap", 4922154be36SSathyanarayana Nujella .stream_name = "Wake on Voice", 493a86d5057SHarsha Priya .cpu_dai_name = "Reference Pin", 494a86d5057SHarsha Priya .codec_name = "snd-soc-dummy", 495a86d5057SHarsha Priya .codec_dai_name = "snd-soc-dummy-dai", 496a86d5057SHarsha Priya .platform_name = "0000:00:1f.3", 497a86d5057SHarsha Priya .init = NULL, 498a86d5057SHarsha Priya .dpcm_capture = 1, 499a86d5057SHarsha Priya .nonatomic = 1, 500a86d5057SHarsha Priya .dynamic = 1, 5012616e27eSYong Zhi .ops = &skylaye_refcap_ops, 5022616e27eSYong Zhi }, 503bc5f6ac9SJeeja KP [SKL_DPCM_AUDIO_DMIC_CP] = { 5042616e27eSYong Zhi .name = "Skl Audio DMIC cap", 5052616e27eSYong Zhi .stream_name = "dmiccap", 5062616e27eSYong Zhi .cpu_dai_name = "DMIC Pin", 5072616e27eSYong Zhi .codec_name = "snd-soc-dummy", 5082616e27eSYong Zhi .codec_dai_name = "snd-soc-dummy-dai", 5092616e27eSYong Zhi .platform_name = "0000:00:1f.3", 5102616e27eSYong Zhi .init = NULL, 5112616e27eSYong Zhi .dpcm_capture = 1, 5122616e27eSYong Zhi .nonatomic = 1, 5132616e27eSYong Zhi .dynamic = 1, 5142616e27eSYong Zhi .ops = &skylake_dmic_ops, 515a86d5057SHarsha Priya }, 516bc5f6ac9SJeeja KP [SKL_DPCM_AUDIO_HDMI1_PB] = { 517bc5f6ac9SJeeja KP .name = "Skl HDMI Port1", 518bc5f6ac9SJeeja KP .stream_name = "Hdmi1", 519bc5f6ac9SJeeja KP .cpu_dai_name = "HDMI1 Pin", 520743ad80eSFang, Yang A .codec_name = "snd-soc-dummy", 521743ad80eSFang, Yang A .codec_dai_name = "snd-soc-dummy-dai", 522743ad80eSFang, Yang A .platform_name = "0000:00:1f.3", 523743ad80eSFang, Yang A .dpcm_playback = 1, 524743ad80eSFang, Yang A .init = NULL, 525bc5f6ac9SJeeja KP .trigger = { 526bc5f6ac9SJeeja KP SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 527bc5f6ac9SJeeja KP .nonatomic = 1, 528bc5f6ac9SJeeja KP .dynamic = 1, 529bc5f6ac9SJeeja KP }, 530bc5f6ac9SJeeja KP [SKL_DPCM_AUDIO_HDMI2_PB] = { 531bc5f6ac9SJeeja KP .name = "Skl HDMI Port2", 532bc5f6ac9SJeeja KP .stream_name = "Hdmi2", 533bc5f6ac9SJeeja KP .cpu_dai_name = "HDMI2 Pin", 534bc5f6ac9SJeeja KP .codec_name = "snd-soc-dummy", 535bc5f6ac9SJeeja KP .codec_dai_name = "snd-soc-dummy-dai", 536bc5f6ac9SJeeja KP .platform_name = "0000:00:1f.3", 537bc5f6ac9SJeeja KP .dpcm_playback = 1, 538bc5f6ac9SJeeja KP .init = NULL, 539bc5f6ac9SJeeja KP .trigger = { 540bc5f6ac9SJeeja KP SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 541bc5f6ac9SJeeja KP .nonatomic = 1, 542bc5f6ac9SJeeja KP .dynamic = 1, 543bc5f6ac9SJeeja KP }, 544bc5f6ac9SJeeja KP [SKL_DPCM_AUDIO_HDMI3_PB] = { 545bc5f6ac9SJeeja KP .name = "Skl HDMI Port3", 546bc5f6ac9SJeeja KP .stream_name = "Hdmi3", 547bc5f6ac9SJeeja KP .cpu_dai_name = "HDMI3 Pin", 548bc5f6ac9SJeeja KP .codec_name = "snd-soc-dummy", 549bc5f6ac9SJeeja KP .codec_dai_name = "snd-soc-dummy-dai", 550bc5f6ac9SJeeja KP .platform_name = "0000:00:1f.3", 551bc5f6ac9SJeeja KP .trigger = { 552bc5f6ac9SJeeja KP SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 553bc5f6ac9SJeeja KP .dpcm_playback = 1, 554bc5f6ac9SJeeja KP .init = NULL, 555743ad80eSFang, Yang A .nonatomic = 1, 556743ad80eSFang, Yang A .dynamic = 1, 557743ad80eSFang, Yang A }, 558743ad80eSFang, Yang A 559a86d5057SHarsha Priya /* Back End DAI links */ 560a86d5057SHarsha Priya { 561a86d5057SHarsha Priya /* SSP0 - Codec */ 562a86d5057SHarsha Priya .name = "SSP0-Codec", 5632f0ad491SMengdong Lin .id = 0, 564a86d5057SHarsha Priya .cpu_dai_name = "SSP0 Pin", 565a86d5057SHarsha Priya .platform_name = "0000:00:1f.3", 566a86d5057SHarsha Priya .no_pcm = 1, 567a86d5057SHarsha Priya .codecs = ssm4567_codec_components, 568a86d5057SHarsha Priya .num_codecs = ARRAY_SIZE(ssm4567_codec_components), 569a86d5057SHarsha Priya .dai_fmt = SND_SOC_DAIFMT_DSP_A | 570a86d5057SHarsha Priya SND_SOC_DAIFMT_IB_NF | 571a86d5057SHarsha Priya SND_SOC_DAIFMT_CBS_CFS, 572a86d5057SHarsha Priya .init = skylake_ssm4567_codec_init, 573a86d5057SHarsha Priya .ignore_pmdown_time = 1, 574a86d5057SHarsha Priya .be_hw_params_fixup = skylake_ssp_fixup, 575a86d5057SHarsha Priya .dpcm_playback = 1, 5765188b95aSJeeja KP .dpcm_capture = 1, 577a86d5057SHarsha Priya }, 578a86d5057SHarsha Priya { 579a86d5057SHarsha Priya /* SSP1 - Codec */ 580a86d5057SHarsha Priya .name = "SSP1-Codec", 5812f0ad491SMengdong Lin .id = 1, 582a86d5057SHarsha Priya .cpu_dai_name = "SSP1 Pin", 583a86d5057SHarsha Priya .platform_name = "0000:00:1f.3", 584a86d5057SHarsha Priya .no_pcm = 1, 585a86d5057SHarsha Priya .codec_name = "i2c-10508825:00", 586a86d5057SHarsha Priya .codec_dai_name = SKL_NUVOTON_CODEC_DAI, 587a86d5057SHarsha Priya .init = skylake_nau8825_codec_init, 588a86d5057SHarsha Priya .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 589a86d5057SHarsha Priya SND_SOC_DAIFMT_CBS_CFS, 590a86d5057SHarsha Priya .ignore_pmdown_time = 1, 591a86d5057SHarsha Priya .be_hw_params_fixup = skylake_ssp_fixup, 592a86d5057SHarsha Priya .ops = &skylake_nau8825_ops, 593a86d5057SHarsha Priya .dpcm_playback = 1, 594a86d5057SHarsha Priya .dpcm_capture = 1, 595a86d5057SHarsha Priya }, 596a86d5057SHarsha Priya { 597a86d5057SHarsha Priya .name = "dmic01", 5982f0ad491SMengdong Lin .id = 2, 599a86d5057SHarsha Priya .cpu_dai_name = "DMIC01 Pin", 600a86d5057SHarsha Priya .codec_name = "dmic-codec", 601a86d5057SHarsha Priya .codec_dai_name = "dmic-hifi", 602a86d5057SHarsha Priya .platform_name = "0000:00:1f.3", 603a86d5057SHarsha Priya .ignore_suspend = 1, 6042616e27eSYong Zhi .be_hw_params_fixup = skylake_dmic_fixup, 605a86d5057SHarsha Priya .dpcm_capture = 1, 606a86d5057SHarsha Priya .no_pcm = 1, 607a86d5057SHarsha Priya }, 608743ad80eSFang, Yang A { 609bc5f6ac9SJeeja KP .name = "iDisp1", 6102f0ad491SMengdong Lin .id = 3, 611bc5f6ac9SJeeja KP .cpu_dai_name = "iDisp1 Pin", 612743ad80eSFang, Yang A .codec_name = "ehdaudio0D2", 613743ad80eSFang, Yang A .codec_dai_name = "intel-hdmi-hifi1", 614743ad80eSFang, Yang A .platform_name = "0000:00:1f.3", 615743ad80eSFang, Yang A .dpcm_playback = 1, 616bc5f6ac9SJeeja KP .init = skylake_hdmi1_init, 617bc5f6ac9SJeeja KP .no_pcm = 1, 618bc5f6ac9SJeeja KP }, 619bc5f6ac9SJeeja KP { 620bc5f6ac9SJeeja KP .name = "iDisp2", 6212f0ad491SMengdong Lin .id = 4, 622bc5f6ac9SJeeja KP .cpu_dai_name = "iDisp2 Pin", 623bc5f6ac9SJeeja KP .codec_name = "ehdaudio0D2", 624bc5f6ac9SJeeja KP .codec_dai_name = "intel-hdmi-hifi2", 625bc5f6ac9SJeeja KP .platform_name = "0000:00:1f.3", 626bc5f6ac9SJeeja KP .init = skylake_hdmi2_init, 627bc5f6ac9SJeeja KP .dpcm_playback = 1, 628bc5f6ac9SJeeja KP .no_pcm = 1, 629bc5f6ac9SJeeja KP }, 630bc5f6ac9SJeeja KP { 631bc5f6ac9SJeeja KP .name = "iDisp3", 6322f0ad491SMengdong Lin .id = 5, 633bc5f6ac9SJeeja KP .cpu_dai_name = "iDisp3 Pin", 634bc5f6ac9SJeeja KP .codec_name = "ehdaudio0D2", 635bc5f6ac9SJeeja KP .codec_dai_name = "intel-hdmi-hifi3", 636bc5f6ac9SJeeja KP .platform_name = "0000:00:1f.3", 637bc5f6ac9SJeeja KP .init = skylake_hdmi3_init, 638bc5f6ac9SJeeja KP .dpcm_playback = 1, 639743ad80eSFang, Yang A .no_pcm = 1, 640743ad80eSFang, Yang A }, 641a86d5057SHarsha Priya }; 642a86d5057SHarsha Priya 64346ed1a27SSubhransu S. Prusty static int skylake_card_late_probe(struct snd_soc_card *card) 64446ed1a27SSubhransu S. Prusty { 64546ed1a27SSubhransu S. Prusty struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card); 64646ed1a27SSubhransu S. Prusty struct skl_hdmi_pcm *pcm; 64746ed1a27SSubhransu S. Prusty int err; 64846ed1a27SSubhransu S. Prusty 64946ed1a27SSubhransu S. Prusty list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { 65046ed1a27SSubhransu S. Prusty err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device); 65146ed1a27SSubhransu S. Prusty if (err < 0) 65246ed1a27SSubhransu S. Prusty return err; 65346ed1a27SSubhransu S. Prusty } 65446ed1a27SSubhransu S. Prusty 65546ed1a27SSubhransu S. Prusty return 0; 65646ed1a27SSubhransu S. Prusty } 65746ed1a27SSubhransu S. Prusty 658a86d5057SHarsha Priya /* skylake audio machine driver for SPT + NAU88L25 */ 659a86d5057SHarsha Priya static struct snd_soc_card skylake_audio_card = { 660a86d5057SHarsha Priya .name = "sklnau8825adi", 661a86d5057SHarsha Priya .owner = THIS_MODULE, 662a86d5057SHarsha Priya .dai_link = skylake_dais, 663a86d5057SHarsha Priya .num_links = ARRAY_SIZE(skylake_dais), 664a86d5057SHarsha Priya .controls = skylake_controls, 665a86d5057SHarsha Priya .num_controls = ARRAY_SIZE(skylake_controls), 666a86d5057SHarsha Priya .dapm_widgets = skylake_widgets, 667a86d5057SHarsha Priya .num_dapm_widgets = ARRAY_SIZE(skylake_widgets), 668a86d5057SHarsha Priya .dapm_routes = skylake_map, 669a86d5057SHarsha Priya .num_dapm_routes = ARRAY_SIZE(skylake_map), 670a86d5057SHarsha Priya .codec_conf = ssm4567_codec_conf, 671a86d5057SHarsha Priya .num_configs = ARRAY_SIZE(ssm4567_codec_conf), 6724c6ebc3eSFang, Yang A .fully_routed = true, 67346ed1a27SSubhransu S. Prusty .late_probe = skylake_card_late_probe, 674a86d5057SHarsha Priya }; 675a86d5057SHarsha Priya 676a86d5057SHarsha Priya static int skylake_audio_probe(struct platform_device *pdev) 677a86d5057SHarsha Priya { 67846ed1a27SSubhransu S. Prusty struct skl_nau88125_private *ctx; 67946ed1a27SSubhransu S. Prusty 68046ed1a27SSubhransu S. Prusty ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 68146ed1a27SSubhransu S. Prusty if (!ctx) 68246ed1a27SSubhransu S. Prusty return -ENOMEM; 68346ed1a27SSubhransu S. Prusty 68446ed1a27SSubhransu S. Prusty INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 68546ed1a27SSubhransu S. Prusty 686a86d5057SHarsha Priya skylake_audio_card.dev = &pdev->dev; 68746ed1a27SSubhransu S. Prusty snd_soc_card_set_drvdata(&skylake_audio_card, ctx); 688a86d5057SHarsha Priya 689a86d5057SHarsha Priya return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); 690a86d5057SHarsha Priya } 691a86d5057SHarsha Priya 692a86d5057SHarsha Priya static struct platform_driver skylake_audio = { 693a86d5057SHarsha Priya .probe = skylake_audio_probe, 694a86d5057SHarsha Priya .driver = { 695a86d5057SHarsha Priya .name = "skl_nau88l25_ssm4567_i2s", 696a86d5057SHarsha Priya .pm = &snd_soc_pm_ops, 697a86d5057SHarsha Priya }, 698a86d5057SHarsha Priya }; 699a86d5057SHarsha Priya 700a86d5057SHarsha Priya module_platform_driver(skylake_audio) 701a86d5057SHarsha Priya 702a86d5057SHarsha Priya /* Module information */ 703a86d5057SHarsha Priya MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); 704a86d5057SHarsha Priya MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); 705a86d5057SHarsha Priya MODULE_AUTHOR("Naveen M <naveen.m@intel.com>"); 706a86d5057SHarsha Priya MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>"); 707a86d5057SHarsha Priya MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>"); 708a86d5057SHarsha Priya MODULE_DESCRIPTION("Intel Audio Machine driver for SKL with NAU88L25 and SSM4567 in I2S Mode"); 709a86d5057SHarsha Priya MODULE_LICENSE("GPL v2"); 710a86d5057SHarsha Priya MODULE_ALIAS("platform:skl_nau88l25_ssm4567_i2s"); 711