mt8183-da7219-max98357.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // mt8183-da7219-max98357.c
  4. // -- MT8183-DA7219-MAX98357 ALSA SoC machine driver
  5. //
  6. // Copyright (c) 2018 MediaTek Inc.
  7. // Author: Shunli Wang <[email protected]>
  8. #include <linux/input.h>
  9. #include <linux/module.h>
  10. #include <linux/of_device.h>
  11. #include <linux/pinctrl/consumer.h>
  12. #include <sound/jack.h>
  13. #include <sound/pcm_params.h>
  14. #include <sound/soc.h>
  15. #include "../../codecs/da7219-aad.h"
  16. #include "../../codecs/da7219.h"
  17. #include "../../codecs/rt1015.h"
  18. #include "../common/mtk-afe-platform-driver.h"
  19. #include "mt8183-afe-common.h"
  20. #define DA7219_CODEC_DAI "da7219-hifi"
  21. #define DA7219_DEV_NAME "da7219.5-001a"
  22. #define RT1015_CODEC_DAI "rt1015-aif"
  23. #define RT1015_DEV0_NAME "rt1015.6-0028"
  24. #define RT1015_DEV1_NAME "rt1015.6-0029"
  25. struct mt8183_da7219_max98357_priv {
  26. struct snd_soc_jack headset_jack, hdmi_jack;
  27. };
  28. static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
  29. struct snd_pcm_hw_params *params)
  30. {
  31. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  32. unsigned int rate = params_rate(params);
  33. unsigned int mclk_fs_ratio = 128;
  34. unsigned int mclk_fs = rate * mclk_fs_ratio;
  35. return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
  36. 0, mclk_fs, SND_SOC_CLOCK_OUT);
  37. }
  38. static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
  39. .hw_params = mt8183_mt6358_i2s_hw_params,
  40. };
  41. static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
  42. struct snd_pcm_hw_params *params)
  43. {
  44. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  45. struct snd_soc_dai *codec_dai;
  46. unsigned int rate = params_rate(params);
  47. unsigned int mclk_fs_ratio = 256;
  48. unsigned int mclk_fs = rate * mclk_fs_ratio;
  49. unsigned int freq;
  50. int ret = 0, j;
  51. ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
  52. mclk_fs, SND_SOC_CLOCK_OUT);
  53. if (ret < 0)
  54. dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
  55. for_each_rtd_codec_dais(rtd, j, codec_dai) {
  56. if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
  57. ret = snd_soc_dai_set_sysclk(codec_dai,
  58. DA7219_CLKSRC_MCLK,
  59. mclk_fs,
  60. SND_SOC_CLOCK_IN);
  61. if (ret < 0)
  62. dev_err(rtd->dev, "failed to set sysclk\n");
  63. if ((rate % 8000) == 0)
  64. freq = DA7219_PLL_FREQ_OUT_98304;
  65. else
  66. freq = DA7219_PLL_FREQ_OUT_90316;
  67. ret = snd_soc_dai_set_pll(codec_dai, 0,
  68. DA7219_SYSCLK_PLL_SRM,
  69. 0, freq);
  70. if (ret)
  71. dev_err(rtd->dev, "failed to start PLL: %d\n",
  72. ret);
  73. }
  74. }
  75. return ret;
  76. }
  77. static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)
  78. {
  79. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  80. struct snd_soc_dai *codec_dai;
  81. int ret = 0, j;
  82. for_each_rtd_codec_dais(rtd, j, codec_dai) {
  83. if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
  84. ret = snd_soc_dai_set_pll(codec_dai,
  85. 0, DA7219_SYSCLK_MCLK, 0, 0);
  86. if (ret < 0) {
  87. dev_err(rtd->dev, "failed to stop PLL: %d\n",
  88. ret);
  89. break;
  90. }
  91. }
  92. }
  93. return ret;
  94. }
  95. static const struct snd_soc_ops mt8183_da7219_i2s_ops = {
  96. .hw_params = mt8183_da7219_i2s_hw_params,
  97. .hw_free = mt8183_da7219_hw_free,
  98. };
  99. static int
  100. mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,
  101. struct snd_pcm_hw_params *params)
  102. {
  103. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  104. unsigned int rate = params_rate(params);
  105. struct snd_soc_dai *codec_dai;
  106. int ret = 0, i;
  107. for_each_rtd_codec_dais(rtd, i, codec_dai) {
  108. if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) ||
  109. !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) {
  110. ret = snd_soc_dai_set_pll(codec_dai, 0,
  111. RT1015_PLL_S_BCLK,
  112. rate * 64, rate * 256);
  113. if (ret) {
  114. dev_err(rtd->dev, "failed to set pll\n");
  115. return ret;
  116. }
  117. ret = snd_soc_dai_set_sysclk(codec_dai,
  118. RT1015_SCLK_S_PLL,
  119. rate * 256,
  120. SND_SOC_CLOCK_IN);
  121. if (ret) {
  122. dev_err(rtd->dev, "failed to set sysclk\n");
  123. return ret;
  124. }
  125. }
  126. }
  127. return mt8183_da7219_i2s_hw_params(substream, params);
  128. }
  129. static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = {
  130. .hw_params = mt8183_da7219_rt1015_i2s_hw_params,
  131. .hw_free = mt8183_da7219_hw_free,
  132. };
  133. static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  134. struct snd_pcm_hw_params *params)
  135. {
  136. /* fix BE i2s format to S32_LE, clean param mask first */
  137. snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
  138. 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
  139. params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
  140. return 0;
  141. }
  142. static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  143. struct snd_pcm_hw_params *params)
  144. {
  145. /* fix BE i2s format to S24_LE, clean param mask first */
  146. snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
  147. 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
  148. params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
  149. return 0;
  150. }
  151. static int
  152. mt8183_da7219_max98357_startup(
  153. struct snd_pcm_substream *substream)
  154. {
  155. static const unsigned int rates[] = {
  156. 48000,
  157. };
  158. static const struct snd_pcm_hw_constraint_list constraints_rates = {
  159. .count = ARRAY_SIZE(rates),
  160. .list = rates,
  161. .mask = 0,
  162. };
  163. static const unsigned int channels[] = {
  164. 2,
  165. };
  166. static const struct snd_pcm_hw_constraint_list constraints_channels = {
  167. .count = ARRAY_SIZE(channels),
  168. .list = channels,
  169. .mask = 0,
  170. };
  171. struct snd_pcm_runtime *runtime = substream->runtime;
  172. snd_pcm_hw_constraint_list(runtime, 0,
  173. SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
  174. runtime->hw.channels_max = 2;
  175. snd_pcm_hw_constraint_list(runtime, 0,
  176. SNDRV_PCM_HW_PARAM_CHANNELS,
  177. &constraints_channels);
  178. runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
  179. snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
  180. return 0;
  181. }
  182. static const struct snd_soc_ops mt8183_da7219_max98357_ops = {
  183. .startup = mt8183_da7219_max98357_startup,
  184. };
  185. static int
  186. mt8183_da7219_max98357_bt_sco_startup(
  187. struct snd_pcm_substream *substream)
  188. {
  189. static const unsigned int rates[] = {
  190. 8000, 16000
  191. };
  192. static const struct snd_pcm_hw_constraint_list constraints_rates = {
  193. .count = ARRAY_SIZE(rates),
  194. .list = rates,
  195. .mask = 0,
  196. };
  197. static const unsigned int channels[] = {
  198. 1,
  199. };
  200. static const struct snd_pcm_hw_constraint_list constraints_channels = {
  201. .count = ARRAY_SIZE(channels),
  202. .list = channels,
  203. .mask = 0,
  204. };
  205. struct snd_pcm_runtime *runtime = substream->runtime;
  206. snd_pcm_hw_constraint_list(runtime, 0,
  207. SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
  208. runtime->hw.channels_max = 1;
  209. snd_pcm_hw_constraint_list(runtime, 0,
  210. SNDRV_PCM_HW_PARAM_CHANNELS,
  211. &constraints_channels);
  212. runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
  213. snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
  214. return 0;
  215. }
  216. static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = {
  217. .startup = mt8183_da7219_max98357_bt_sco_startup,
  218. };
  219. /* FE */
  220. SND_SOC_DAILINK_DEFS(playback1,
  221. DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
  222. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  223. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  224. SND_SOC_DAILINK_DEFS(playback2,
  225. DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
  226. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  227. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  228. SND_SOC_DAILINK_DEFS(playback3,
  229. DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
  230. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  231. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  232. SND_SOC_DAILINK_DEFS(capture1,
  233. DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
  234. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  235. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  236. SND_SOC_DAILINK_DEFS(capture2,
  237. DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
  238. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  239. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  240. SND_SOC_DAILINK_DEFS(capture3,
  241. DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
  242. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  243. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  244. SND_SOC_DAILINK_DEFS(capture_mono,
  245. DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
  246. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  247. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  248. SND_SOC_DAILINK_DEFS(playback_hdmi,
  249. DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
  250. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  251. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  252. /* BE */
  253. SND_SOC_DAILINK_DEFS(primary_codec,
  254. DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
  255. DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
  256. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  257. SND_SOC_DAILINK_DEFS(pcm1,
  258. DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
  259. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  260. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  261. SND_SOC_DAILINK_DEFS(pcm2,
  262. DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
  263. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  264. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  265. SND_SOC_DAILINK_DEFS(i2s0,
  266. DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
  267. DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
  268. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  269. SND_SOC_DAILINK_DEFS(i2s1,
  270. DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
  271. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  272. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  273. SND_SOC_DAILINK_DEFS(i2s2,
  274. DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
  275. DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
  276. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  277. SND_SOC_DAILINK_DEFS(i2s3_max98357a,
  278. DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
  279. DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),
  280. COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
  281. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  282. SND_SOC_DAILINK_DEFS(i2s3_rt1015,
  283. DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
  284. DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),
  285. COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI),
  286. COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
  287. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  288. SND_SOC_DAILINK_DEFS(i2s3_rt1015p,
  289. DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
  290. DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"),
  291. COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
  292. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  293. SND_SOC_DAILINK_DEFS(i2s5,
  294. DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
  295. DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
  296. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  297. SND_SOC_DAILINK_DEFS(tdm,
  298. DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
  299. DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
  300. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  301. static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
  302. {
  303. struct mt8183_da7219_max98357_priv *priv =
  304. snd_soc_card_get_drvdata(rtd->card);
  305. int ret;
  306. ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
  307. &priv->hdmi_jack);
  308. if (ret)
  309. return ret;
  310. return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component,
  311. &priv->hdmi_jack, NULL);
  312. }
  313. static int mt8183_bt_init(struct snd_soc_pcm_runtime *rtd)
  314. {
  315. struct snd_soc_component *cmpnt_afe =
  316. snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
  317. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
  318. int ret;
  319. ret = mt8183_dai_i2s_set_share(afe, "I2S5", "I2S0");
  320. if (ret) {
  321. dev_err(rtd->dev, "Failed to set up shared clocks\n");
  322. return ret;
  323. }
  324. return 0;
  325. }
  326. static int mt8183_da7219_init(struct snd_soc_pcm_runtime *rtd)
  327. {
  328. struct snd_soc_component *cmpnt_afe =
  329. snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
  330. struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
  331. int ret;
  332. ret = mt8183_dai_i2s_set_share(afe, "I2S2", "I2S3");
  333. if (ret) {
  334. dev_err(rtd->dev, "Failed to set up shared clocks\n");
  335. return ret;
  336. }
  337. return 0;
  338. }
  339. static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
  340. /* FE */
  341. {
  342. .name = "Playback_1",
  343. .stream_name = "Playback_1",
  344. .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
  345. SND_SOC_DPCM_TRIGGER_PRE},
  346. .dynamic = 1,
  347. .dpcm_playback = 1,
  348. .ops = &mt8183_da7219_max98357_ops,
  349. SND_SOC_DAILINK_REG(playback1),
  350. },
  351. {
  352. .name = "Playback_2",
  353. .stream_name = "Playback_2",
  354. .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
  355. SND_SOC_DPCM_TRIGGER_PRE},
  356. .dynamic = 1,
  357. .dpcm_playback = 1,
  358. .ops = &mt8183_da7219_max98357_bt_sco_ops,
  359. SND_SOC_DAILINK_REG(playback2),
  360. },
  361. {
  362. .name = "Playback_3",
  363. .stream_name = "Playback_3",
  364. .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
  365. SND_SOC_DPCM_TRIGGER_PRE},
  366. .dynamic = 1,
  367. .dpcm_playback = 1,
  368. SND_SOC_DAILINK_REG(playback3),
  369. },
  370. {
  371. .name = "Capture_1",
  372. .stream_name = "Capture_1",
  373. .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
  374. SND_SOC_DPCM_TRIGGER_PRE},
  375. .dynamic = 1,
  376. .dpcm_capture = 1,
  377. .ops = &mt8183_da7219_max98357_bt_sco_ops,
  378. SND_SOC_DAILINK_REG(capture1),
  379. },
  380. {
  381. .name = "Capture_2",
  382. .stream_name = "Capture_2",
  383. .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
  384. SND_SOC_DPCM_TRIGGER_PRE},
  385. .dynamic = 1,
  386. .dpcm_capture = 1,
  387. SND_SOC_DAILINK_REG(capture2),
  388. },
  389. {
  390. .name = "Capture_3",
  391. .stream_name = "Capture_3",
  392. .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
  393. SND_SOC_DPCM_TRIGGER_PRE},
  394. .dynamic = 1,
  395. .dpcm_capture = 1,
  396. .ops = &mt8183_da7219_max98357_ops,
  397. SND_SOC_DAILINK_REG(capture3),
  398. },
  399. {
  400. .name = "Capture_Mono_1",
  401. .stream_name = "Capture_Mono_1",
  402. .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
  403. SND_SOC_DPCM_TRIGGER_PRE},
  404. .dynamic = 1,
  405. .dpcm_capture = 1,
  406. SND_SOC_DAILINK_REG(capture_mono),
  407. },
  408. {
  409. .name = "Playback_HDMI",
  410. .stream_name = "Playback_HDMI",
  411. .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
  412. SND_SOC_DPCM_TRIGGER_PRE},
  413. .dynamic = 1,
  414. .dpcm_playback = 1,
  415. SND_SOC_DAILINK_REG(playback_hdmi),
  416. },
  417. /* BE */
  418. {
  419. .name = "Primary Codec",
  420. .no_pcm = 1,
  421. .dpcm_playback = 1,
  422. .dpcm_capture = 1,
  423. .ignore_suspend = 1,
  424. SND_SOC_DAILINK_REG(primary_codec),
  425. },
  426. {
  427. .name = "PCM 1",
  428. .no_pcm = 1,
  429. .dpcm_playback = 1,
  430. .dpcm_capture = 1,
  431. .ignore_suspend = 1,
  432. SND_SOC_DAILINK_REG(pcm1),
  433. },
  434. {
  435. .name = "PCM 2",
  436. .no_pcm = 1,
  437. .dpcm_playback = 1,
  438. .dpcm_capture = 1,
  439. .ignore_suspend = 1,
  440. SND_SOC_DAILINK_REG(pcm2),
  441. },
  442. {
  443. .name = "I2S0",
  444. .no_pcm = 1,
  445. .dpcm_capture = 1,
  446. .ignore_suspend = 1,
  447. .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
  448. .ops = &mt8183_mt6358_i2s_ops,
  449. SND_SOC_DAILINK_REG(i2s0),
  450. },
  451. {
  452. .name = "I2S1",
  453. .no_pcm = 1,
  454. .dpcm_playback = 1,
  455. .ignore_suspend = 1,
  456. .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
  457. .ops = &mt8183_mt6358_i2s_ops,
  458. SND_SOC_DAILINK_REG(i2s1),
  459. },
  460. {
  461. .name = "I2S2",
  462. .no_pcm = 1,
  463. .dpcm_capture = 1,
  464. .ignore_suspend = 1,
  465. .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
  466. .ops = &mt8183_da7219_i2s_ops,
  467. .init = &mt8183_da7219_init,
  468. SND_SOC_DAILINK_REG(i2s2),
  469. },
  470. {
  471. .name = "I2S3",
  472. .no_pcm = 1,
  473. .dpcm_playback = 1,
  474. .ignore_suspend = 1,
  475. },
  476. {
  477. .name = "I2S5",
  478. .no_pcm = 1,
  479. .dpcm_playback = 1,
  480. .ignore_suspend = 1,
  481. .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
  482. .ops = &mt8183_mt6358_i2s_ops,
  483. .init = &mt8183_bt_init,
  484. SND_SOC_DAILINK_REG(i2s5),
  485. },
  486. {
  487. .name = "TDM",
  488. .no_pcm = 1,
  489. .dai_fmt = SND_SOC_DAIFMT_I2S |
  490. SND_SOC_DAIFMT_IB_IF |
  491. SND_SOC_DAIFMT_CBM_CFM,
  492. .dpcm_playback = 1,
  493. .ignore_suspend = 1,
  494. .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
  495. .ignore = 1,
  496. .init = mt8183_da7219_max98357_hdmi_init,
  497. SND_SOC_DAILINK_REG(tdm),
  498. },
  499. };
  500. static int
  501. mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)
  502. {
  503. int ret;
  504. struct mt8183_da7219_max98357_priv *priv =
  505. snd_soc_card_get_drvdata(component->card);
  506. /* Enable Headset and 4 Buttons Jack detection */
  507. ret = snd_soc_card_jack_new(component->card,
  508. "Headset Jack",
  509. SND_JACK_HEADSET |
  510. SND_JACK_BTN_0 | SND_JACK_BTN_1 |
  511. SND_JACK_BTN_2 | SND_JACK_BTN_3 |
  512. SND_JACK_LINEOUT,
  513. &priv->headset_jack);
  514. if (ret)
  515. return ret;
  516. snd_jack_set_key(
  517. priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
  518. snd_jack_set_key(
  519. priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
  520. snd_jack_set_key(
  521. priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
  522. snd_jack_set_key(
  523. priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
  524. da7219_aad_jack_det(component, &priv->headset_jack);
  525. return 0;
  526. }
  527. static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
  528. .dlc = COMP_EMPTY(),
  529. .init = mt8183_da7219_max98357_headset_init,
  530. };
  531. static struct snd_soc_codec_conf mt6358_codec_conf[] = {
  532. {
  533. .dlc = COMP_CODEC_CONF("mt6358-sound"),
  534. .name_prefix = "Mt6358",
  535. },
  536. };
  537. static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = {
  538. SOC_DAPM_PIN_SWITCH("Speakers"),
  539. };
  540. static const
  541. struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = {
  542. SND_SOC_DAPM_SPK("Speakers", NULL),
  543. SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
  544. "aud_tdm_out_on", "aud_tdm_out_off"),
  545. };
  546. static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {
  547. {"Speakers", NULL, "Speaker"},
  548. {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
  549. };
  550. static struct snd_soc_card mt8183_da7219_max98357_card = {
  551. .name = "mt8183_da7219_max98357",
  552. .owner = THIS_MODULE,
  553. .controls = mt8183_da7219_max98357_snd_controls,
  554. .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
  555. .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
  556. .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
  557. .dapm_routes = mt8183_da7219_max98357_dapm_routes,
  558. .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
  559. .dai_link = mt8183_da7219_dai_links,
  560. .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
  561. .aux_dev = &mt8183_da7219_max98357_headset_dev,
  562. .num_aux_devs = 1,
  563. .codec_conf = mt6358_codec_conf,
  564. .num_configs = ARRAY_SIZE(mt6358_codec_conf),
  565. };
  566. static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = {
  567. {
  568. .dlc = COMP_CODEC_CONF("mt6358-sound"),
  569. .name_prefix = "Mt6358",
  570. },
  571. {
  572. .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
  573. .name_prefix = "Left",
  574. },
  575. {
  576. .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
  577. .name_prefix = "Right",
  578. },
  579. };
  580. static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = {
  581. SOC_DAPM_PIN_SWITCH("Left Spk"),
  582. SOC_DAPM_PIN_SWITCH("Right Spk"),
  583. };
  584. static const
  585. struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = {
  586. SND_SOC_DAPM_SPK("Left Spk", NULL),
  587. SND_SOC_DAPM_SPK("Right Spk", NULL),
  588. SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
  589. "aud_tdm_out_on", "aud_tdm_out_off"),
  590. };
  591. static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = {
  592. {"Left Spk", NULL, "Left SPO"},
  593. {"Right Spk", NULL, "Right SPO"},
  594. {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
  595. };
  596. static struct snd_soc_card mt8183_da7219_rt1015_card = {
  597. .name = "mt8183_da7219_rt1015",
  598. .owner = THIS_MODULE,
  599. .controls = mt8183_da7219_rt1015_snd_controls,
  600. .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls),
  601. .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets,
  602. .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets),
  603. .dapm_routes = mt8183_da7219_rt1015_dapm_routes,
  604. .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes),
  605. .dai_link = mt8183_da7219_dai_links,
  606. .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
  607. .aux_dev = &mt8183_da7219_max98357_headset_dev,
  608. .num_aux_devs = 1,
  609. .codec_conf = mt8183_da7219_rt1015_codec_conf,
  610. .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf),
  611. };
  612. static struct snd_soc_card mt8183_da7219_rt1015p_card = {
  613. .name = "mt8183_da7219_rt1015p",
  614. .owner = THIS_MODULE,
  615. .controls = mt8183_da7219_max98357_snd_controls,
  616. .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
  617. .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
  618. .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
  619. .dapm_routes = mt8183_da7219_max98357_dapm_routes,
  620. .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
  621. .dai_link = mt8183_da7219_dai_links,
  622. .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
  623. .aux_dev = &mt8183_da7219_max98357_headset_dev,
  624. .num_aux_devs = 1,
  625. .codec_conf = mt6358_codec_conf,
  626. .num_configs = ARRAY_SIZE(mt6358_codec_conf),
  627. };
  628. static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
  629. {
  630. struct snd_soc_card *card;
  631. struct device_node *platform_node, *hdmi_codec;
  632. struct snd_soc_dai_link *dai_link;
  633. struct mt8183_da7219_max98357_priv *priv;
  634. struct pinctrl *pinctrl;
  635. int ret, i;
  636. platform_node = of_parse_phandle(pdev->dev.of_node,
  637. "mediatek,platform", 0);
  638. if (!platform_node) {
  639. dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
  640. return -EINVAL;
  641. }
  642. card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
  643. if (!card) {
  644. ret = -EINVAL;
  645. goto put_platform_node;
  646. }
  647. card->dev = &pdev->dev;
  648. hdmi_codec = of_parse_phandle(pdev->dev.of_node,
  649. "mediatek,hdmi-codec", 0);
  650. for_each_card_prelinks(card, i, dai_link) {
  651. if (strcmp(dai_link->name, "I2S3") == 0) {
  652. if (card == &mt8183_da7219_max98357_card) {
  653. dai_link->be_hw_params_fixup =
  654. mt8183_i2s_hw_params_fixup;
  655. dai_link->ops = &mt8183_da7219_i2s_ops;
  656. dai_link->cpus = i2s3_max98357a_cpus;
  657. dai_link->num_cpus =
  658. ARRAY_SIZE(i2s3_max98357a_cpus);
  659. dai_link->codecs = i2s3_max98357a_codecs;
  660. dai_link->num_codecs =
  661. ARRAY_SIZE(i2s3_max98357a_codecs);
  662. dai_link->platforms = i2s3_max98357a_platforms;
  663. dai_link->num_platforms =
  664. ARRAY_SIZE(i2s3_max98357a_platforms);
  665. } else if (card == &mt8183_da7219_rt1015_card) {
  666. dai_link->be_hw_params_fixup =
  667. mt8183_rt1015_i2s_hw_params_fixup;
  668. dai_link->ops = &mt8183_da7219_rt1015_i2s_ops;
  669. dai_link->cpus = i2s3_rt1015_cpus;
  670. dai_link->num_cpus =
  671. ARRAY_SIZE(i2s3_rt1015_cpus);
  672. dai_link->codecs = i2s3_rt1015_codecs;
  673. dai_link->num_codecs =
  674. ARRAY_SIZE(i2s3_rt1015_codecs);
  675. dai_link->platforms = i2s3_rt1015_platforms;
  676. dai_link->num_platforms =
  677. ARRAY_SIZE(i2s3_rt1015_platforms);
  678. } else if (card == &mt8183_da7219_rt1015p_card) {
  679. dai_link->be_hw_params_fixup =
  680. mt8183_rt1015_i2s_hw_params_fixup;
  681. dai_link->ops = &mt8183_da7219_i2s_ops;
  682. dai_link->cpus = i2s3_rt1015p_cpus;
  683. dai_link->num_cpus =
  684. ARRAY_SIZE(i2s3_rt1015p_cpus);
  685. dai_link->codecs = i2s3_rt1015p_codecs;
  686. dai_link->num_codecs =
  687. ARRAY_SIZE(i2s3_rt1015p_codecs);
  688. dai_link->platforms = i2s3_rt1015p_platforms;
  689. dai_link->num_platforms =
  690. ARRAY_SIZE(i2s3_rt1015p_platforms);
  691. }
  692. }
  693. if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
  694. dai_link->codecs->of_node = hdmi_codec;
  695. dai_link->ignore = 0;
  696. }
  697. if (!dai_link->platforms->name)
  698. dai_link->platforms->of_node = platform_node;
  699. }
  700. mt8183_da7219_max98357_headset_dev.dlc.of_node =
  701. of_parse_phandle(pdev->dev.of_node,
  702. "mediatek,headset-codec", 0);
  703. if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
  704. dev_err(&pdev->dev,
  705. "Property 'mediatek,headset-codec' missing/invalid\n");
  706. ret = -EINVAL;
  707. goto put_hdmi_codec;
  708. }
  709. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  710. if (!priv) {
  711. ret = -ENOMEM;
  712. goto put_hdmi_codec;
  713. }
  714. snd_soc_card_set_drvdata(card, priv);
  715. pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
  716. if (IS_ERR(pinctrl)) {
  717. ret = PTR_ERR(pinctrl);
  718. dev_err(&pdev->dev, "%s failed to select default state %d\n",
  719. __func__, ret);
  720. goto put_hdmi_codec;
  721. }
  722. ret = devm_snd_soc_register_card(&pdev->dev, card);
  723. put_hdmi_codec:
  724. of_node_put(hdmi_codec);
  725. put_platform_node:
  726. of_node_put(platform_node);
  727. return ret;
  728. }
  729. #ifdef CONFIG_OF
  730. static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {
  731. {
  732. .compatible = "mediatek,mt8183_da7219_max98357",
  733. .data = &mt8183_da7219_max98357_card,
  734. },
  735. {
  736. .compatible = "mediatek,mt8183_da7219_rt1015",
  737. .data = &mt8183_da7219_rt1015_card,
  738. },
  739. {
  740. .compatible = "mediatek,mt8183_da7219_rt1015p",
  741. .data = &mt8183_da7219_rt1015p_card,
  742. },
  743. {}
  744. };
  745. #endif
  746. static struct platform_driver mt8183_da7219_max98357_driver = {
  747. .driver = {
  748. .name = "mt8183_da7219",
  749. #ifdef CONFIG_OF
  750. .of_match_table = mt8183_da7219_max98357_dt_match,
  751. #endif
  752. .pm = &snd_soc_pm_ops,
  753. },
  754. .probe = mt8183_da7219_max98357_dev_probe,
  755. };
  756. module_platform_driver(mt8183_da7219_max98357_driver);
  757. /* Module information */
  758. MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");
  759. MODULE_AUTHOR("Shunli Wang <[email protected]>");
  760. MODULE_LICENSE("GPL v2");
  761. MODULE_ALIAS("mt8183_da7219_max98357 soc card");