skl_nau88l25_max98357a.c 17 KB

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