sof_realtek_common.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. //
  3. // Copyright(c) 2020 Intel Corporation
  4. #include <linux/device.h>
  5. #include <linux/kernel.h>
  6. #include <sound/pcm.h>
  7. #include <sound/pcm_params.h>
  8. #include <sound/soc.h>
  9. #include <sound/soc-acpi.h>
  10. #include <sound/soc-dai.h>
  11. #include <sound/soc-dapm.h>
  12. #include <sound/sof.h>
  13. #include <uapi/sound/asound.h>
  14. #include "../../codecs/rt1011.h"
  15. #include "../../codecs/rt1015.h"
  16. #include "../../codecs/rt1308.h"
  17. #include "../common/soc-intel-quirks.h"
  18. #include "sof_realtek_common.h"
  19. /*
  20. * Common structures and functions
  21. */
  22. static const struct snd_kcontrol_new realtek_2spk_kcontrols[] = {
  23. SOC_DAPM_PIN_SWITCH("Left Spk"),
  24. SOC_DAPM_PIN_SWITCH("Right Spk"),
  25. };
  26. static const struct snd_soc_dapm_widget realtek_2spk_widgets[] = {
  27. SND_SOC_DAPM_SPK("Left Spk", NULL),
  28. SND_SOC_DAPM_SPK("Right Spk", NULL),
  29. };
  30. static const struct snd_kcontrol_new realtek_4spk_kcontrols[] = {
  31. SOC_DAPM_PIN_SWITCH("WL Ext Spk"),
  32. SOC_DAPM_PIN_SWITCH("WR Ext Spk"),
  33. SOC_DAPM_PIN_SWITCH("TL Ext Spk"),
  34. SOC_DAPM_PIN_SWITCH("TR Ext Spk"),
  35. };
  36. static const struct snd_soc_dapm_widget realtek_4spk_widgets[] = {
  37. SND_SOC_DAPM_SPK("WL Ext Spk", NULL),
  38. SND_SOC_DAPM_SPK("WR Ext Spk", NULL),
  39. SND_SOC_DAPM_SPK("TL Ext Spk", NULL),
  40. SND_SOC_DAPM_SPK("TR Ext Spk", NULL),
  41. };
  42. /* helper function to get the number of specific codec */
  43. static unsigned int get_num_codecs(const char *hid)
  44. {
  45. struct acpi_device *adev;
  46. unsigned int dev_num = 0;
  47. for_each_acpi_dev_match(adev, hid, NULL, -1)
  48. dev_num++;
  49. return dev_num;
  50. }
  51. /*
  52. * Realtek ALC1011
  53. */
  54. static const struct snd_soc_dapm_route speaker_map_lr[] = {
  55. /* speaker */
  56. { "Left Spk", NULL, "Left SPO" },
  57. { "Right Spk", NULL, "Right SPO" },
  58. };
  59. static const struct snd_soc_dapm_route rt1011_4spk_routes[] = {
  60. {"WL Ext Spk", NULL, "WL SPO" },
  61. {"WR Ext Spk", NULL, "WR SPO" },
  62. {"TL Ext Spk", NULL, "TL SPO" },
  63. {"TR Ext Spk", NULL, "TR SPO" },
  64. };
  65. static struct snd_soc_codec_conf rt1011_2spk_codec_confs[] = {
  66. {
  67. .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME),
  68. .name_prefix = "Left",
  69. },
  70. {
  71. .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME),
  72. .name_prefix = "Right",
  73. },
  74. };
  75. static struct snd_soc_codec_conf rt1011_4spk_codec_confs[] = {
  76. {
  77. .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME),
  78. .name_prefix = "WL",
  79. },
  80. {
  81. .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME),
  82. .name_prefix = "WR",
  83. },
  84. {
  85. .dlc = COMP_CODEC_CONF(RT1011_DEV2_NAME),
  86. .name_prefix = "TL",
  87. },
  88. {
  89. .dlc = COMP_CODEC_CONF(RT1011_DEV3_NAME),
  90. .name_prefix = "TR",
  91. },
  92. };
  93. static struct snd_soc_dai_link_component rt1011_dai_link_components[] = {
  94. {
  95. .name = RT1011_DEV0_NAME,
  96. .dai_name = RT1011_CODEC_DAI,
  97. },
  98. {
  99. .name = RT1011_DEV1_NAME,
  100. .dai_name = RT1011_CODEC_DAI,
  101. },
  102. {
  103. .name = RT1011_DEV2_NAME,
  104. .dai_name = RT1011_CODEC_DAI,
  105. },
  106. {
  107. .name = RT1011_DEV3_NAME,
  108. .dai_name = RT1011_CODEC_DAI,
  109. },
  110. };
  111. static const struct {
  112. unsigned int tx;
  113. unsigned int rx;
  114. } rt1011_tdm_mask[] = {
  115. {.tx = 0x4, .rx = 0x1},
  116. {.tx = 0x8, .rx = 0x2},
  117. {.tx = 0x1, .rx = 0x1},
  118. {.tx = 0x2, .rx = 0x2},
  119. };
  120. static int rt1011_hw_params(struct snd_pcm_substream *substream,
  121. struct snd_pcm_hw_params *params)
  122. {
  123. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  124. struct snd_soc_dai *codec_dai;
  125. int srate, i, ret = 0;
  126. srate = params_rate(params);
  127. for_each_rtd_codec_dais(rtd, i, codec_dai) {
  128. /* 100 Fs to drive 24 bit data */
  129. ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK,
  130. 100 * srate, 256 * srate);
  131. if (ret < 0) {
  132. dev_err(codec_dai->dev, "fail to set pll, ret %d\n",
  133. ret);
  134. return ret;
  135. }
  136. ret = snd_soc_dai_set_sysclk(codec_dai, RT1011_FS_SYS_PRE_S_PLL1,
  137. 256 * srate, SND_SOC_CLOCK_IN);
  138. if (ret < 0) {
  139. dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n",
  140. ret);
  141. return ret;
  142. }
  143. if (i >= ARRAY_SIZE(rt1011_tdm_mask)) {
  144. dev_err(codec_dai->dev, "invalid codec index %d\n",
  145. i);
  146. return -ENODEV;
  147. }
  148. ret = snd_soc_dai_set_tdm_slot(codec_dai, rt1011_tdm_mask[i].tx,
  149. rt1011_tdm_mask[i].rx, 4,
  150. params_width(params));
  151. if (ret < 0) {
  152. dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
  153. ret);
  154. return ret;
  155. }
  156. }
  157. return 0;
  158. }
  159. static const struct snd_soc_ops rt1011_ops = {
  160. .hw_params = rt1011_hw_params,
  161. };
  162. static int rt1011_init(struct snd_soc_pcm_runtime *rtd)
  163. {
  164. struct snd_soc_card *card = rtd->card;
  165. unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
  166. int ret;
  167. switch (num_codecs) {
  168. case 2:
  169. if (!soc_intel_is_cml()) {
  170. ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
  171. ARRAY_SIZE(realtek_2spk_widgets));
  172. if (ret) {
  173. dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n",
  174. ret);
  175. return ret;
  176. }
  177. ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
  178. ARRAY_SIZE(realtek_2spk_kcontrols));
  179. if (ret) {
  180. dev_err(rtd->dev, "fail to add rt1011 kcontrols, ret %d\n",
  181. ret);
  182. return ret;
  183. }
  184. ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr,
  185. ARRAY_SIZE(speaker_map_lr));
  186. if (ret) {
  187. dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
  188. ret);
  189. return ret;
  190. }
  191. break;
  192. }
  193. /*
  194. * register speaker widgets "WL Ext Spk" and "WR Ext Spk" to
  195. * keep backward compatible with cml devices
  196. */
  197. fallthrough;
  198. case 4:
  199. ret = snd_soc_dapm_new_controls(&card->dapm, realtek_4spk_widgets,
  200. num_codecs);
  201. if (ret) {
  202. dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n",
  203. ret);
  204. return ret;
  205. }
  206. ret = snd_soc_add_card_controls(card, realtek_4spk_kcontrols,
  207. num_codecs);
  208. if (ret) {
  209. dev_err(rtd->dev, "fail to add rt1011 controls, ret %d\n",
  210. ret);
  211. return ret;
  212. }
  213. ret = snd_soc_dapm_add_routes(&card->dapm, rt1011_4spk_routes,
  214. num_codecs);
  215. if (ret) {
  216. dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
  217. ret);
  218. return ret;
  219. }
  220. break;
  221. default:
  222. dev_err(rtd->dev, "rt1011: invalid num_codecs %d\n", num_codecs);
  223. return -EINVAL;
  224. }
  225. return ret;
  226. }
  227. void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link)
  228. {
  229. unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
  230. link->codecs = rt1011_dai_link_components;
  231. switch (num_codecs) {
  232. case 2:
  233. case 4:
  234. link->num_codecs = num_codecs;
  235. break;
  236. default:
  237. dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs);
  238. break;
  239. }
  240. link->init = rt1011_init;
  241. link->ops = &rt1011_ops;
  242. }
  243. EXPORT_SYMBOL_NS(sof_rt1011_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
  244. void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card)
  245. {
  246. unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
  247. switch (num_codecs) {
  248. case 2:
  249. if (soc_intel_is_cml()) {
  250. /*
  251. * use name prefix 'WL' and 'WR' for speaker widgets to
  252. * keep backward compatible with cml devices
  253. */
  254. card->codec_conf = rt1011_4spk_codec_confs;
  255. } else {
  256. card->codec_conf = rt1011_2spk_codec_confs;
  257. }
  258. card->num_configs = num_codecs;
  259. break;
  260. case 4:
  261. card->codec_conf = rt1011_4spk_codec_confs;
  262. card->num_configs = ARRAY_SIZE(rt1011_4spk_codec_confs);
  263. break;
  264. default:
  265. dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs);
  266. break;
  267. }
  268. }
  269. EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
  270. /*
  271. * rt1015: i2c mode driver for ALC1015 and ALC1015Q
  272. * rt1015p: auto-mode driver for ALC1015, ALC1015Q, and ALC1015Q-VB
  273. *
  274. * For stereo output, there are always two amplifiers on the board.
  275. * However, the ACPI implements only one device instance (UID=0) if they
  276. * are sharing the same enable pin. This is the case of rt1015p.
  277. */
  278. static const struct snd_soc_dapm_route rt1015p_dapm_routes[] = {
  279. /* speaker */
  280. { "Left Spk", NULL, "Speaker" },
  281. { "Right Spk", NULL, "Speaker" },
  282. };
  283. static struct snd_soc_dai_link_component rt1015p_dai_link_components[] = {
  284. {
  285. .name = RT1015P_DEV0_NAME,
  286. .dai_name = RT1015P_CODEC_DAI,
  287. },
  288. };
  289. static int rt1015p_hw_params(struct snd_pcm_substream *substream,
  290. struct snd_pcm_hw_params *params)
  291. {
  292. /* reserved for debugging purpose */
  293. return 0;
  294. }
  295. static const struct snd_soc_ops rt1015p_ops = {
  296. .hw_params = rt1015p_hw_params,
  297. };
  298. static int rt1015p_init(struct snd_soc_pcm_runtime *rtd)
  299. {
  300. struct snd_soc_card *card = rtd->card;
  301. int ret;
  302. ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
  303. ARRAY_SIZE(realtek_2spk_widgets));
  304. if (ret) {
  305. dev_err(rtd->dev, "fail to add rt1015p widgets, ret %d\n", ret);
  306. return ret;
  307. }
  308. ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
  309. ARRAY_SIZE(realtek_2spk_kcontrols));
  310. if (ret) {
  311. dev_err(rtd->dev, "fail to add rt1015p kcontrols, ret %d\n", ret);
  312. return ret;
  313. }
  314. ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_dapm_routes,
  315. ARRAY_SIZE(rt1015p_dapm_routes));
  316. if (ret)
  317. dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
  318. return ret;
  319. }
  320. void sof_rt1015p_dai_link(struct snd_soc_dai_link *link)
  321. {
  322. link->codecs = rt1015p_dai_link_components;
  323. link->num_codecs = ARRAY_SIZE(rt1015p_dai_link_components);
  324. link->init = rt1015p_init;
  325. link->ops = &rt1015p_ops;
  326. }
  327. EXPORT_SYMBOL_NS(sof_rt1015p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
  328. void sof_rt1015p_codec_conf(struct snd_soc_card *card)
  329. {
  330. }
  331. EXPORT_SYMBOL_NS(sof_rt1015p_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
  332. /*
  333. * RT1015 audio amplifier
  334. */
  335. static const struct {
  336. unsigned int tx;
  337. unsigned int rx;
  338. } rt1015_tdm_mask[] = {
  339. {.tx = 0x0, .rx = 0x1},
  340. {.tx = 0x0, .rx = 0x2},
  341. };
  342. static int rt1015_hw_params(struct snd_pcm_substream *substream,
  343. struct snd_pcm_hw_params *params)
  344. {
  345. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  346. struct snd_soc_dai_link *dai_link = rtd->dai_link;
  347. struct snd_soc_dai *codec_dai;
  348. int i, clk_freq;
  349. int ret = 0;
  350. clk_freq = sof_dai_get_bclk(rtd);
  351. if (clk_freq <= 0) {
  352. dev_err(rtd->dev, "fail to get bclk freq, ret %d\n", clk_freq);
  353. return -EINVAL;
  354. }
  355. for_each_rtd_codec_dais(rtd, i, codec_dai) {
  356. ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
  357. clk_freq,
  358. params_rate(params) * 256);
  359. if (ret) {
  360. dev_err(codec_dai->dev, "fail to set pll, ret %d\n",
  361. ret);
  362. return ret;
  363. }
  364. ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
  365. params_rate(params) * 256,
  366. SND_SOC_CLOCK_IN);
  367. if (ret) {
  368. dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n",
  369. ret);
  370. return ret;
  371. }
  372. switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  373. case SND_SOC_DAIFMT_DSP_A:
  374. case SND_SOC_DAIFMT_DSP_B:
  375. /* 4-slot TDM */
  376. ret = snd_soc_dai_set_tdm_slot(codec_dai,
  377. rt1015_tdm_mask[i].tx,
  378. rt1015_tdm_mask[i].rx,
  379. 4,
  380. params_width(params));
  381. if (ret < 0) {
  382. dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
  383. ret);
  384. return ret;
  385. }
  386. break;
  387. default:
  388. dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
  389. break;
  390. }
  391. }
  392. return ret;
  393. }
  394. static const struct snd_soc_ops rt1015_ops = {
  395. .hw_params = rt1015_hw_params,
  396. };
  397. static struct snd_soc_codec_conf rt1015_amp_conf[] = {
  398. {
  399. .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
  400. .name_prefix = "Left",
  401. },
  402. {
  403. .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
  404. .name_prefix = "Right",
  405. },
  406. };
  407. static struct snd_soc_dai_link_component rt1015_components[] = {
  408. {
  409. .name = RT1015_DEV0_NAME,
  410. .dai_name = RT1015_CODEC_DAI,
  411. },
  412. {
  413. .name = RT1015_DEV1_NAME,
  414. .dai_name = RT1015_CODEC_DAI,
  415. },
  416. };
  417. static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd)
  418. {
  419. struct snd_soc_card *card = rtd->card;
  420. unsigned int num_codecs = get_num_codecs(RT1015_ACPI_HID);
  421. int ret;
  422. switch (num_codecs) {
  423. case 2:
  424. ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
  425. ARRAY_SIZE(realtek_2spk_widgets));
  426. if (ret) {
  427. dev_err(rtd->dev, "fail to add rt1015 widgets, ret %d\n",
  428. ret);
  429. return ret;
  430. }
  431. ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
  432. ARRAY_SIZE(realtek_2spk_kcontrols));
  433. if (ret) {
  434. dev_err(rtd->dev, "fail to add rt1015 kcontrols, ret %d\n",
  435. ret);
  436. return ret;
  437. }
  438. ret = snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr,
  439. ARRAY_SIZE(speaker_map_lr));
  440. if (ret) {
  441. dev_err(rtd->dev, "fail to add rt1015 routes, ret %d\n",
  442. ret);
  443. return ret;
  444. }
  445. break;
  446. default:
  447. dev_err(rtd->dev, "rt1015: invalid num_codecs %d\n", num_codecs);
  448. return -EINVAL;
  449. }
  450. return ret;
  451. }
  452. void sof_rt1015_codec_conf(struct snd_soc_card *card)
  453. {
  454. card->codec_conf = rt1015_amp_conf;
  455. card->num_configs = ARRAY_SIZE(rt1015_amp_conf);
  456. }
  457. EXPORT_SYMBOL_NS(sof_rt1015_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
  458. void sof_rt1015_dai_link(struct snd_soc_dai_link *link)
  459. {
  460. link->codecs = rt1015_components;
  461. link->num_codecs = ARRAY_SIZE(rt1015_components);
  462. link->init = speaker_codec_init_lr;
  463. link->ops = &rt1015_ops;
  464. }
  465. EXPORT_SYMBOL_NS(sof_rt1015_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
  466. /*
  467. * RT1308 audio amplifier
  468. */
  469. static const struct snd_kcontrol_new rt1308_kcontrols[] = {
  470. SOC_DAPM_PIN_SWITCH("Speakers"),
  471. };
  472. static const struct snd_soc_dapm_widget rt1308_dapm_widgets[] = {
  473. SND_SOC_DAPM_SPK("Speakers", NULL),
  474. };
  475. static const struct snd_soc_dapm_route rt1308_dapm_routes[] = {
  476. /* speaker */
  477. {"Speakers", NULL, "SPOL"},
  478. {"Speakers", NULL, "SPOR"},
  479. };
  480. static struct snd_soc_dai_link_component rt1308_components[] = {
  481. {
  482. .name = RT1308_DEV0_NAME,
  483. .dai_name = RT1308_CODEC_DAI,
  484. }
  485. };
  486. static int rt1308_init(struct snd_soc_pcm_runtime *rtd)
  487. {
  488. struct snd_soc_card *card = rtd->card;
  489. int ret;
  490. ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_dapm_widgets,
  491. ARRAY_SIZE(rt1308_dapm_widgets));
  492. if (ret) {
  493. dev_err(rtd->dev, "fail to add dapm controls, ret %d\n", ret);
  494. return ret;
  495. }
  496. ret = snd_soc_add_card_controls(card, rt1308_kcontrols,
  497. ARRAY_SIZE(rt1308_kcontrols));
  498. if (ret) {
  499. dev_err(rtd->dev, "fail to add card controls, ret %d\n", ret);
  500. return ret;
  501. }
  502. ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_dapm_routes,
  503. ARRAY_SIZE(rt1308_dapm_routes));
  504. if (ret)
  505. dev_err(rtd->dev, "fail to add dapm routes, ret %d\n", ret);
  506. return ret;
  507. }
  508. static int rt1308_hw_params(struct snd_pcm_substream *substream,
  509. struct snd_pcm_hw_params *params)
  510. {
  511. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  512. struct snd_soc_card *card = rtd->card;
  513. struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
  514. int clk_id, clk_freq, pll_out;
  515. int ret;
  516. clk_id = RT1308_PLL_S_MCLK;
  517. /* get the tplg configured mclk. */
  518. clk_freq = sof_dai_get_mclk(rtd);
  519. pll_out = params_rate(params) * 512;
  520. /* Set rt1308 pll */
  521. ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out);
  522. if (ret < 0) {
  523. dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", ret);
  524. return ret;
  525. }
  526. /* Set rt1308 sysclk */
  527. ret = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out,
  528. SND_SOC_CLOCK_IN);
  529. if (ret < 0)
  530. dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", ret);
  531. return ret;
  532. }
  533. static const struct snd_soc_ops rt1308_ops = {
  534. .hw_params = rt1308_hw_params,
  535. };
  536. void sof_rt1308_dai_link(struct snd_soc_dai_link *link)
  537. {
  538. link->codecs = rt1308_components;
  539. link->num_codecs = ARRAY_SIZE(rt1308_components);
  540. link->init = rt1308_init;
  541. link->ops = &rt1308_ops;
  542. }
  543. EXPORT_SYMBOL_NS(sof_rt1308_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
  544. /*
  545. * 2-amp Configuration for RT1019
  546. */
  547. static const struct snd_soc_dapm_route rt1019p_dapm_routes[] = {
  548. /* speaker */
  549. { "Left Spk", NULL, "Speaker" },
  550. { "Right Spk", NULL, "Speaker" },
  551. };
  552. static struct snd_soc_dai_link_component rt1019p_components[] = {
  553. {
  554. .name = RT1019P_DEV0_NAME,
  555. .dai_name = RT1019P_CODEC_DAI,
  556. },
  557. };
  558. static int rt1019p_init(struct snd_soc_pcm_runtime *rtd)
  559. {
  560. struct snd_soc_card *card = rtd->card;
  561. int ret;
  562. ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
  563. ARRAY_SIZE(realtek_2spk_widgets));
  564. if (ret) {
  565. dev_err(rtd->dev, "fail to add rt1019p widgets, ret %d\n", ret);
  566. return ret;
  567. }
  568. ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
  569. ARRAY_SIZE(realtek_2spk_kcontrols));
  570. if (ret) {
  571. dev_err(rtd->dev, "fail to add rt1019p kcontrols, ret %d\n", ret);
  572. return ret;
  573. }
  574. ret = snd_soc_dapm_add_routes(&card->dapm, rt1019p_dapm_routes,
  575. ARRAY_SIZE(rt1019p_dapm_routes));
  576. if (ret) {
  577. dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
  578. return ret;
  579. }
  580. return ret;
  581. }
  582. void sof_rt1019p_dai_link(struct snd_soc_dai_link *link)
  583. {
  584. link->codecs = rt1019p_components;
  585. link->num_codecs = ARRAY_SIZE(rt1019p_components);
  586. link->init = rt1019p_init;
  587. }
  588. EXPORT_SYMBOL_NS(sof_rt1019p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
  589. MODULE_DESCRIPTION("ASoC Intel SOF Realtek helpers");
  590. MODULE_LICENSE("GPL");