skl_nau88l25_max98357a.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. /*
  2. * Intel Skylake I2S Machine Driver with MAXIM98357A
  3. * and NAU88L25
  4. *
  5. * Copyright (C) 2015, Intel Corporation. All rights reserved.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License version
  9. * 2 as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include <linux/module.h>
  17. #include <linux/platform_device.h>
  18. #include <sound/core.h>
  19. #include <sound/jack.h>
  20. #include <sound/pcm.h>
  21. #include <sound/pcm_params.h>
  22. #include <sound/soc.h>
  23. #include "../../codecs/nau8825.h"
  24. #include "../../codecs/hdac_hdmi.h"
  25. #include "../skylake/skl.h"
  26. #define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
  27. #define SKL_MAXIM_CODEC_DAI "HiFi"
  28. #define DMIC_CH(p) p->list[p->count-1]
  29. static struct snd_soc_jack skylake_headset;
  30. static struct snd_soc_card skylake_audio_card;
  31. static const struct snd_pcm_hw_constraint_list *dmic_constraints;
  32. struct skl_hdmi_pcm {
  33. struct list_head head;
  34. struct snd_soc_dai *codec_dai;
  35. int device;
  36. };
  37. struct skl_nau8825_private {
  38. struct list_head hdmi_pcm_list;
  39. };
  40. enum {
  41. SKL_DPCM_AUDIO_PB = 0,
  42. SKL_DPCM_AUDIO_CP,
  43. SKL_DPCM_AUDIO_REF_CP,
  44. SKL_DPCM_AUDIO_DMIC_CP,
  45. SKL_DPCM_AUDIO_HDMI1_PB,
  46. SKL_DPCM_AUDIO_HDMI2_PB,
  47. SKL_DPCM_AUDIO_HDMI3_PB,
  48. };
  49. static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
  50. {
  51. struct snd_soc_pcm_runtime *rtd;
  52. list_for_each_entry(rtd, &card->rtd_list, list) {
  53. if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI,
  54. strlen(SKL_NUVOTON_CODEC_DAI)))
  55. return rtd->codec_dai;
  56. }
  57. return NULL;
  58. }
  59. static int platform_clock_control(struct snd_soc_dapm_widget *w,
  60. struct snd_kcontrol *k, int event)
  61. {
  62. struct snd_soc_dapm_context *dapm = w->dapm;
  63. struct snd_soc_card *card = dapm->card;
  64. struct snd_soc_dai *codec_dai;
  65. int ret;
  66. codec_dai = skl_get_codec_dai(card);
  67. if (!codec_dai) {
  68. dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
  69. return -EIO;
  70. }
  71. if (SND_SOC_DAPM_EVENT_ON(event)) {
  72. ret = snd_soc_dai_set_sysclk(codec_dai,
  73. NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
  74. if (ret < 0) {
  75. dev_err(card->dev, "set sysclk err = %d\n", ret);
  76. return -EIO;
  77. }
  78. } else {
  79. ret = snd_soc_dai_set_sysclk(codec_dai,
  80. NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN);
  81. if (ret < 0) {
  82. dev_err(card->dev, "set sysclk err = %d\n", ret);
  83. return -EIO;
  84. }
  85. }
  86. return ret;
  87. }
  88. static const struct snd_kcontrol_new skylake_controls[] = {
  89. SOC_DAPM_PIN_SWITCH("Headphone Jack"),
  90. SOC_DAPM_PIN_SWITCH("Headset Mic"),
  91. SOC_DAPM_PIN_SWITCH("Spk"),
  92. };
  93. static const struct snd_soc_dapm_widget skylake_widgets[] = {
  94. SND_SOC_DAPM_HP("Headphone Jack", NULL),
  95. SND_SOC_DAPM_MIC("Headset Mic", NULL),
  96. SND_SOC_DAPM_SPK("Spk", NULL),
  97. SND_SOC_DAPM_MIC("SoC DMIC", NULL),
  98. SND_SOC_DAPM_SPK("DP", NULL),
  99. SND_SOC_DAPM_SPK("HDMI", NULL),
  100. SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
  101. platform_clock_control, SND_SOC_DAPM_PRE_PMU |
  102. SND_SOC_DAPM_POST_PMD),
  103. };
  104. static const struct snd_soc_dapm_route skylake_map[] = {
  105. /* HP jack connectors - unknown if we have jack detection */
  106. { "Headphone Jack", NULL, "HPOL" },
  107. { "Headphone Jack", NULL, "HPOR" },
  108. /* speaker */
  109. { "Spk", NULL, "Speaker" },
  110. /* other jacks */
  111. { "MIC", NULL, "Headset Mic" },
  112. { "DMic", NULL, "SoC DMIC" },
  113. {"HDMI", NULL, "hif5 Output"},
  114. {"DP", NULL, "hif6 Output"},
  115. /* CODEC BE connections */
  116. { "HiFi Playback", NULL, "ssp0 Tx" },
  117. { "ssp0 Tx", NULL, "codec0_out" },
  118. { "Playback", NULL, "ssp1 Tx" },
  119. { "ssp1 Tx", NULL, "codec1_out" },
  120. { "codec0_in", NULL, "ssp1 Rx" },
  121. { "ssp1 Rx", NULL, "Capture" },
  122. /* DMIC */
  123. { "dmic01_hifi", NULL, "DMIC01 Rx" },
  124. { "DMIC01 Rx", NULL, "DMIC AIF" },
  125. { "hifi3", NULL, "iDisp3 Tx"},
  126. { "iDisp3 Tx", NULL, "iDisp3_out"},
  127. { "hifi2", NULL, "iDisp2 Tx"},
  128. { "iDisp2 Tx", NULL, "iDisp2_out"},
  129. { "hifi1", NULL, "iDisp1 Tx"},
  130. { "iDisp1 Tx", NULL, "iDisp1_out"},
  131. { "Headphone Jack", NULL, "Platform Clock" },
  132. { "Headset Mic", NULL, "Platform Clock" },
  133. };
  134. static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
  135. struct snd_pcm_hw_params *params)
  136. {
  137. struct snd_interval *rate = hw_param_interval(params,
  138. SNDRV_PCM_HW_PARAM_RATE);
  139. struct snd_interval *channels = hw_param_interval(params,
  140. SNDRV_PCM_HW_PARAM_CHANNELS);
  141. struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
  142. /* The ADSP will covert the FE rate to 48k, stereo */
  143. rate->min = rate->max = 48000;
  144. channels->min = channels->max = 2;
  145. /* set SSP0 to 24 bit */
  146. snd_mask_none(fmt);
  147. snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
  148. return 0;
  149. }
  150. static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
  151. {
  152. int ret;
  153. struct snd_soc_codec *codec = rtd->codec;
  154. /*
  155. * Headset buttons map to the google Reference headset.
  156. * These can be configured by userspace.
  157. */
  158. ret = snd_soc_card_jack_new(&skylake_audio_card, "Headset Jack",
  159. SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
  160. SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset,
  161. NULL, 0);
  162. if (ret) {
  163. dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
  164. return ret;
  165. }
  166. nau8825_enable_jack_detect(codec, &skylake_headset);
  167. snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
  168. return ret;
  169. }
  170. static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
  171. {
  172. struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card);
  173. struct snd_soc_dai *dai = rtd->codec_dai;
  174. struct skl_hdmi_pcm *pcm;
  175. pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
  176. if (!pcm)
  177. return -ENOMEM;
  178. pcm->device = SKL_DPCM_AUDIO_HDMI1_PB;
  179. pcm->codec_dai = dai;
  180. list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
  181. return 0;
  182. }
  183. static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
  184. {
  185. struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card);
  186. struct snd_soc_dai *dai = rtd->codec_dai;
  187. struct skl_hdmi_pcm *pcm;
  188. pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
  189. if (!pcm)
  190. return -ENOMEM;
  191. pcm->device = SKL_DPCM_AUDIO_HDMI2_PB;
  192. pcm->codec_dai = dai;
  193. list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
  194. return 0;
  195. }
  196. static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
  197. {
  198. struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card);
  199. struct snd_soc_dai *dai = rtd->codec_dai;
  200. struct skl_hdmi_pcm *pcm;
  201. pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
  202. if (!pcm)
  203. return -ENOMEM;
  204. pcm->device = SKL_DPCM_AUDIO_HDMI3_PB;
  205. pcm->codec_dai = dai;
  206. list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
  207. return 0;
  208. }
  209. static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
  210. {
  211. struct snd_soc_dapm_context *dapm;
  212. struct snd_soc_component *component = rtd->cpu_dai->component;
  213. dapm = snd_soc_component_get_dapm(component);
  214. snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
  215. return 0;
  216. }
  217. static unsigned int rates[] = {
  218. 48000,
  219. };
  220. static struct snd_pcm_hw_constraint_list constraints_rates = {
  221. .count = ARRAY_SIZE(rates),
  222. .list = rates,
  223. .mask = 0,
  224. };
  225. static unsigned int channels[] = {
  226. 2,
  227. };
  228. static struct snd_pcm_hw_constraint_list constraints_channels = {
  229. .count = ARRAY_SIZE(channels),
  230. .list = channels,
  231. .mask = 0,
  232. };
  233. static int skl_fe_startup(struct snd_pcm_substream *substream)
  234. {
  235. struct snd_pcm_runtime *runtime = substream->runtime;
  236. /*
  237. * On this platform for PCM device we support,
  238. * 48Khz
  239. * stereo
  240. * 16 bit audio
  241. */
  242. runtime->hw.channels_max = 2;
  243. snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
  244. &constraints_channels);
  245. runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
  246. snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
  247. snd_pcm_hw_constraint_list(runtime, 0,
  248. SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
  249. return 0;
  250. }
  251. static const struct snd_soc_ops skylake_nau8825_fe_ops = {
  252. .startup = skl_fe_startup,
  253. };
  254. static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream,
  255. struct snd_pcm_hw_params *params)
  256. {
  257. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  258. struct snd_soc_dai *codec_dai = rtd->codec_dai;
  259. int ret;
  260. ret = snd_soc_dai_set_sysclk(codec_dai,
  261. NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
  262. if (ret < 0)
  263. dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
  264. return ret;
  265. }
  266. static struct snd_soc_ops skylake_nau8825_ops = {
  267. .hw_params = skylake_nau8825_hw_params,
  268. };
  269. static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
  270. struct snd_pcm_hw_params *params)
  271. {
  272. struct snd_interval *channels = hw_param_interval(params,
  273. SNDRV_PCM_HW_PARAM_CHANNELS);
  274. if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2)
  275. channels->min = channels->max = 2;
  276. else
  277. channels->min = channels->max = 4;
  278. return 0;
  279. }
  280. static unsigned int channels_dmic[] = {
  281. 2, 4,
  282. };
  283. static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
  284. .count = ARRAY_SIZE(channels_dmic),
  285. .list = channels_dmic,
  286. .mask = 0,
  287. };
  288. static const unsigned int dmic_2ch[] = {
  289. 2,
  290. };
  291. static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = {
  292. .count = ARRAY_SIZE(dmic_2ch),
  293. .list = dmic_2ch,
  294. .mask = 0,
  295. };
  296. static int skylake_dmic_startup(struct snd_pcm_substream *substream)
  297. {
  298. struct snd_pcm_runtime *runtime = substream->runtime;
  299. runtime->hw.channels_max = DMIC_CH(dmic_constraints);
  300. snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
  301. dmic_constraints);
  302. return snd_pcm_hw_constraint_list(substream->runtime, 0,
  303. SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
  304. }
  305. static struct snd_soc_ops skylake_dmic_ops = {
  306. .startup = skylake_dmic_startup,
  307. };
  308. static unsigned int rates_16000[] = {
  309. 16000,
  310. };
  311. static struct snd_pcm_hw_constraint_list constraints_16000 = {
  312. .count = ARRAY_SIZE(rates_16000),
  313. .list = rates_16000,
  314. };
  315. static const unsigned int ch_mono[] = {
  316. 1,
  317. };
  318. static const struct snd_pcm_hw_constraint_list constraints_refcap = {
  319. .count = ARRAY_SIZE(ch_mono),
  320. .list = ch_mono,
  321. };
  322. static int skylake_refcap_startup(struct snd_pcm_substream *substream)
  323. {
  324. substream->runtime->hw.channels_max = 1;
  325. snd_pcm_hw_constraint_list(substream->runtime, 0,
  326. SNDRV_PCM_HW_PARAM_CHANNELS,
  327. &constraints_refcap);
  328. return snd_pcm_hw_constraint_list(substream->runtime, 0,
  329. SNDRV_PCM_HW_PARAM_RATE,
  330. &constraints_16000);
  331. }
  332. static struct snd_soc_ops skylaye_refcap_ops = {
  333. .startup = skylake_refcap_startup,
  334. };
  335. /* skylake digital audio interface glue - connects codec <--> CPU */
  336. static struct snd_soc_dai_link skylake_dais[] = {
  337. /* Front End DAI links */
  338. [SKL_DPCM_AUDIO_PB] = {
  339. .name = "Skl Audio Port",
  340. .stream_name = "Audio",
  341. .cpu_dai_name = "System Pin",
  342. .platform_name = "0000:00:1f.3",
  343. .dynamic = 1,
  344. .codec_name = "snd-soc-dummy",
  345. .codec_dai_name = "snd-soc-dummy-dai",
  346. .nonatomic = 1,
  347. .init = skylake_nau8825_fe_init,
  348. .trigger = {
  349. SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
  350. .dpcm_playback = 1,
  351. .ops = &skylake_nau8825_fe_ops,
  352. },
  353. [SKL_DPCM_AUDIO_CP] = {
  354. .name = "Skl Audio Capture Port",
  355. .stream_name = "Audio Record",
  356. .cpu_dai_name = "System Pin",
  357. .platform_name = "0000:00:1f.3",
  358. .dynamic = 1,
  359. .codec_name = "snd-soc-dummy",
  360. .codec_dai_name = "snd-soc-dummy-dai",
  361. .nonatomic = 1,
  362. .trigger = {
  363. SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
  364. .dpcm_capture = 1,
  365. .ops = &skylake_nau8825_fe_ops,
  366. },
  367. [SKL_DPCM_AUDIO_REF_CP] = {
  368. .name = "Skl Audio Reference cap",
  369. .stream_name = "Wake on Voice",
  370. .cpu_dai_name = "Reference Pin",
  371. .codec_name = "snd-soc-dummy",
  372. .codec_dai_name = "snd-soc-dummy-dai",
  373. .platform_name = "0000:00:1f.3",
  374. .init = NULL,
  375. .dpcm_capture = 1,
  376. .nonatomic = 1,
  377. .dynamic = 1,
  378. .ops = &skylaye_refcap_ops,
  379. },
  380. [SKL_DPCM_AUDIO_DMIC_CP] = {
  381. .name = "Skl Audio DMIC cap",
  382. .stream_name = "dmiccap",
  383. .cpu_dai_name = "DMIC Pin",
  384. .codec_name = "snd-soc-dummy",
  385. .codec_dai_name = "snd-soc-dummy-dai",
  386. .platform_name = "0000:00:1f.3",
  387. .init = NULL,
  388. .dpcm_capture = 1,
  389. .nonatomic = 1,
  390. .dynamic = 1,
  391. .ops = &skylake_dmic_ops,
  392. },
  393. [SKL_DPCM_AUDIO_HDMI1_PB] = {
  394. .name = "Skl HDMI Port1",
  395. .stream_name = "Hdmi1",
  396. .cpu_dai_name = "HDMI1 Pin",
  397. .codec_name = "snd-soc-dummy",
  398. .codec_dai_name = "snd-soc-dummy-dai",
  399. .platform_name = "0000:00:1f.3",
  400. .dpcm_playback = 1,
  401. .init = NULL,
  402. .trigger = {
  403. SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
  404. .nonatomic = 1,
  405. .dynamic = 1,
  406. },
  407. [SKL_DPCM_AUDIO_HDMI2_PB] = {
  408. .name = "Skl HDMI Port2",
  409. .stream_name = "Hdmi2",
  410. .cpu_dai_name = "HDMI2 Pin",
  411. .codec_name = "snd-soc-dummy",
  412. .codec_dai_name = "snd-soc-dummy-dai",
  413. .platform_name = "0000:00:1f.3",
  414. .dpcm_playback = 1,
  415. .init = NULL,
  416. .trigger = {
  417. SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
  418. .nonatomic = 1,
  419. .dynamic = 1,
  420. },
  421. [SKL_DPCM_AUDIO_HDMI3_PB] = {
  422. .name = "Skl HDMI Port3",
  423. .stream_name = "Hdmi3",
  424. .cpu_dai_name = "HDMI3 Pin",
  425. .codec_name = "snd-soc-dummy",
  426. .codec_dai_name = "snd-soc-dummy-dai",
  427. .platform_name = "0000:00:1f.3",
  428. .trigger = {
  429. SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
  430. .dpcm_playback = 1,
  431. .init = NULL,
  432. .nonatomic = 1,
  433. .dynamic = 1,
  434. },
  435. /* Back End DAI links */
  436. {
  437. /* SSP0 - Codec */
  438. .name = "SSP0-Codec",
  439. .id = 0,
  440. .cpu_dai_name = "SSP0 Pin",
  441. .platform_name = "0000:00:1f.3",
  442. .no_pcm = 1,
  443. .codec_name = "MX98357A:00",
  444. .codec_dai_name = SKL_MAXIM_CODEC_DAI,
  445. .dai_fmt = SND_SOC_DAIFMT_I2S |
  446. SND_SOC_DAIFMT_NB_NF |
  447. SND_SOC_DAIFMT_CBS_CFS,
  448. .ignore_pmdown_time = 1,
  449. .be_hw_params_fixup = skylake_ssp_fixup,
  450. .dpcm_playback = 1,
  451. },
  452. {
  453. /* SSP1 - Codec */
  454. .name = "SSP1-Codec",
  455. .id = 1,
  456. .cpu_dai_name = "SSP1 Pin",
  457. .platform_name = "0000:00:1f.3",
  458. .no_pcm = 1,
  459. .codec_name = "i2c-10508825:00",
  460. .codec_dai_name = SKL_NUVOTON_CODEC_DAI,
  461. .init = skylake_nau8825_codec_init,
  462. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  463. SND_SOC_DAIFMT_CBS_CFS,
  464. .ignore_pmdown_time = 1,
  465. .be_hw_params_fixup = skylake_ssp_fixup,
  466. .ops = &skylake_nau8825_ops,
  467. .dpcm_playback = 1,
  468. .dpcm_capture = 1,
  469. },
  470. {
  471. .name = "dmic01",
  472. .id = 2,
  473. .cpu_dai_name = "DMIC01 Pin",
  474. .codec_name = "dmic-codec",
  475. .codec_dai_name = "dmic-hifi",
  476. .platform_name = "0000:00:1f.3",
  477. .be_hw_params_fixup = skylake_dmic_fixup,
  478. .ignore_suspend = 1,
  479. .dpcm_capture = 1,
  480. .no_pcm = 1,
  481. },
  482. {
  483. .name = "iDisp1",
  484. .id = 3,
  485. .cpu_dai_name = "iDisp1 Pin",
  486. .codec_name = "ehdaudio0D2",
  487. .codec_dai_name = "intel-hdmi-hifi1",
  488. .platform_name = "0000:00:1f.3",
  489. .dpcm_playback = 1,
  490. .init = skylake_hdmi1_init,
  491. .no_pcm = 1,
  492. },
  493. {
  494. .name = "iDisp2",
  495. .id = 4,
  496. .cpu_dai_name = "iDisp2 Pin",
  497. .codec_name = "ehdaudio0D2",
  498. .codec_dai_name = "intel-hdmi-hifi2",
  499. .platform_name = "0000:00:1f.3",
  500. .init = skylake_hdmi2_init,
  501. .dpcm_playback = 1,
  502. .no_pcm = 1,
  503. },
  504. {
  505. .name = "iDisp3",
  506. .id = 5,
  507. .cpu_dai_name = "iDisp3 Pin",
  508. .codec_name = "ehdaudio0D2",
  509. .codec_dai_name = "intel-hdmi-hifi3",
  510. .platform_name = "0000:00:1f.3",
  511. .init = skylake_hdmi3_init,
  512. .dpcm_playback = 1,
  513. .no_pcm = 1,
  514. },
  515. };
  516. static int skylake_card_late_probe(struct snd_soc_card *card)
  517. {
  518. struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
  519. struct skl_hdmi_pcm *pcm;
  520. int err;
  521. list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
  522. err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device);
  523. if (err < 0)
  524. return err;
  525. }
  526. return 0;
  527. }
  528. /* skylake audio machine driver for SPT + NAU88L25 */
  529. static struct snd_soc_card skylake_audio_card = {
  530. .name = "sklnau8825max",
  531. .owner = THIS_MODULE,
  532. .dai_link = skylake_dais,
  533. .num_links = ARRAY_SIZE(skylake_dais),
  534. .controls = skylake_controls,
  535. .num_controls = ARRAY_SIZE(skylake_controls),
  536. .dapm_widgets = skylake_widgets,
  537. .num_dapm_widgets = ARRAY_SIZE(skylake_widgets),
  538. .dapm_routes = skylake_map,
  539. .num_dapm_routes = ARRAY_SIZE(skylake_map),
  540. .fully_routed = true,
  541. .late_probe = skylake_card_late_probe,
  542. };
  543. static int skylake_audio_probe(struct platform_device *pdev)
  544. {
  545. struct skl_nau8825_private *ctx;
  546. struct skl_machine_pdata *pdata;
  547. ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
  548. if (!ctx)
  549. return -ENOMEM;
  550. INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
  551. skylake_audio_card.dev = &pdev->dev;
  552. snd_soc_card_set_drvdata(&skylake_audio_card, ctx);
  553. pdata = dev_get_drvdata(&pdev->dev);
  554. if (pdata)
  555. dmic_constraints = pdata->dmic_num == 2 ?
  556. &constraints_dmic_2ch : &constraints_dmic_channels;
  557. return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
  558. }
  559. static const struct platform_device_id skl_board_ids[] = {
  560. { .name = "skl_n88l25_m98357a" },
  561. { .name = "kbl_n88l25_m98357a" },
  562. { }
  563. };
  564. static struct platform_driver skylake_audio = {
  565. .probe = skylake_audio_probe,
  566. .driver = {
  567. .name = "skl_n88l25_m98357a",
  568. .pm = &snd_soc_pm_ops,
  569. },
  570. .id_table = skl_board_ids,
  571. };
  572. module_platform_driver(skylake_audio)
  573. /* Module information */
  574. MODULE_DESCRIPTION("Audio Machine driver-NAU88L25 & MAX98357A in I2S mode");
  575. MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com");
  576. MODULE_LICENSE("GPL v2");
  577. MODULE_ALIAS("platform:skl_n88l25_m98357a");
  578. MODULE_ALIAS("platform:kbl_n88l25_m98357a");