rk3399_gru_sound.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Rockchip machine ASoC driver for boards using MAX98357A/RT5514/DA7219
  4. *
  5. * Copyright (c) 2016, ROCKCHIP CORPORATION. All rights reserved.
  6. */
  7. #include <linux/module.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/slab.h>
  10. #include <linux/gpio.h>
  11. #include <linux/of_gpio.h>
  12. #include <linux/delay.h>
  13. #include <linux/spi/spi.h>
  14. #include <linux/i2c.h>
  15. #include <linux/input.h>
  16. #include <sound/core.h>
  17. #include <sound/jack.h>
  18. #include <sound/pcm.h>
  19. #include <sound/pcm_params.h>
  20. #include <sound/soc.h>
  21. #include "rockchip_i2s.h"
  22. #include "../codecs/da7219.h"
  23. #include "../codecs/da7219-aad.h"
  24. #include "../codecs/rt5514.h"
  25. #define DRV_NAME "rk3399-gru-sound"
  26. #define SOUND_FS 256
  27. static unsigned int dmic_wakeup_delay;
  28. static struct snd_soc_jack rockchip_sound_jack;
  29. /* Headset jack detection DAPM pins */
  30. static struct snd_soc_jack_pin rockchip_sound_jack_pins[] = {
  31. {
  32. .pin = "Headphones",
  33. .mask = SND_JACK_HEADPHONE,
  34. },
  35. {
  36. .pin = "Headset Mic",
  37. .mask = SND_JACK_MICROPHONE,
  38. },
  39. };
  40. static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
  41. SND_SOC_DAPM_HP("Headphones", NULL),
  42. SND_SOC_DAPM_SPK("Speakers", NULL),
  43. SND_SOC_DAPM_MIC("Headset Mic", NULL),
  44. SND_SOC_DAPM_MIC("Int Mic", NULL),
  45. SND_SOC_DAPM_LINE("HDMI", NULL),
  46. };
  47. static const struct snd_kcontrol_new rockchip_controls[] = {
  48. SOC_DAPM_PIN_SWITCH("Headphones"),
  49. SOC_DAPM_PIN_SWITCH("Speakers"),
  50. SOC_DAPM_PIN_SWITCH("Headset Mic"),
  51. SOC_DAPM_PIN_SWITCH("Int Mic"),
  52. SOC_DAPM_PIN_SWITCH("HDMI"),
  53. };
  54. static int rockchip_sound_max98357a_hw_params(struct snd_pcm_substream *substream,
  55. struct snd_pcm_hw_params *params)
  56. {
  57. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  58. unsigned int mclk;
  59. int ret;
  60. mclk = params_rate(params) * SOUND_FS;
  61. ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0);
  62. if (ret) {
  63. dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
  64. __func__, mclk, ret);
  65. return ret;
  66. }
  67. return 0;
  68. }
  69. static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
  70. struct snd_pcm_hw_params *params)
  71. {
  72. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  73. struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
  74. struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
  75. unsigned int mclk;
  76. int ret;
  77. mclk = params_rate(params) * SOUND_FS;
  78. ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
  79. SND_SOC_CLOCK_OUT);
  80. if (ret < 0) {
  81. dev_err(rtd->card->dev, "Can't set cpu clock out %d\n", ret);
  82. return ret;
  83. }
  84. ret = snd_soc_dai_set_sysclk(codec_dai, RT5514_SCLK_S_MCLK,
  85. mclk, SND_SOC_CLOCK_IN);
  86. if (ret) {
  87. dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
  88. __func__, params_rate(params) * 512, ret);
  89. return ret;
  90. }
  91. /* Wait for DMIC stable */
  92. msleep(dmic_wakeup_delay);
  93. return 0;
  94. }
  95. static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
  96. struct snd_pcm_hw_params *params)
  97. {
  98. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  99. struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
  100. struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
  101. int mclk, ret;
  102. /* in bypass mode, the mclk has to be one of the frequencies below */
  103. switch (params_rate(params)) {
  104. case 8000:
  105. case 16000:
  106. case 24000:
  107. case 32000:
  108. case 48000:
  109. case 64000:
  110. case 96000:
  111. mclk = 12288000;
  112. break;
  113. case 11025:
  114. case 22050:
  115. case 44100:
  116. case 88200:
  117. mclk = 11289600;
  118. break;
  119. default:
  120. return -EINVAL;
  121. }
  122. ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
  123. SND_SOC_CLOCK_OUT);
  124. if (ret < 0) {
  125. dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret);
  126. return ret;
  127. }
  128. ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
  129. SND_SOC_CLOCK_IN);
  130. if (ret < 0) {
  131. dev_err(codec_dai->dev, "Can't set codec clock in %d\n", ret);
  132. return ret;
  133. }
  134. ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
  135. if (ret < 0) {
  136. dev_err(codec_dai->dev, "Can't set pll sysclk mclk %d\n", ret);
  137. return ret;
  138. }
  139. return 0;
  140. }
  141. static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
  142. {
  143. struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
  144. struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
  145. int ret;
  146. /* We need default MCLK and PLL settings for the accessory detection */
  147. ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000,
  148. SND_SOC_CLOCK_IN);
  149. if (ret < 0) {
  150. dev_err(codec_dai->dev, "Init can't set codec clock in %d\n", ret);
  151. return ret;
  152. }
  153. ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
  154. if (ret < 0) {
  155. dev_err(codec_dai->dev, "Init can't set pll sysclk mclk %d\n", ret);
  156. return ret;
  157. }
  158. /* Enable Headset and 4 Buttons Jack detection */
  159. ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
  160. SND_JACK_HEADSET | SND_JACK_LINEOUT |
  161. SND_JACK_BTN_0 | SND_JACK_BTN_1 |
  162. SND_JACK_BTN_2 | SND_JACK_BTN_3,
  163. &rockchip_sound_jack,
  164. rockchip_sound_jack_pins,
  165. ARRAY_SIZE(rockchip_sound_jack_pins));
  166. if (ret) {
  167. dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret);
  168. return ret;
  169. }
  170. snd_jack_set_key(
  171. rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
  172. snd_jack_set_key(
  173. rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
  174. snd_jack_set_key(
  175. rockchip_sound_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
  176. snd_jack_set_key(
  177. rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
  178. da7219_aad_jack_det(component, &rockchip_sound_jack);
  179. return 0;
  180. }
  181. static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream,
  182. struct snd_pcm_hw_params *params)
  183. {
  184. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  185. unsigned int mclk;
  186. int ret;
  187. mclk = params_rate(params) * SOUND_FS;
  188. ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0);
  189. if (ret) {
  190. dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
  191. __func__, mclk, ret);
  192. return ret;
  193. }
  194. /* Wait for DMIC stable */
  195. msleep(dmic_wakeup_delay);
  196. return 0;
  197. }
  198. static int rockchip_sound_startup(struct snd_pcm_substream *substream)
  199. {
  200. struct snd_pcm_runtime *runtime = substream->runtime;
  201. runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
  202. return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
  203. 8000, 96000);
  204. }
  205. static const struct snd_soc_ops rockchip_sound_max98357a_ops = {
  206. .startup = rockchip_sound_startup,
  207. .hw_params = rockchip_sound_max98357a_hw_params,
  208. };
  209. static const struct snd_soc_ops rockchip_sound_rt5514_ops = {
  210. .startup = rockchip_sound_startup,
  211. .hw_params = rockchip_sound_rt5514_hw_params,
  212. };
  213. static const struct snd_soc_ops rockchip_sound_da7219_ops = {
  214. .startup = rockchip_sound_startup,
  215. .hw_params = rockchip_sound_da7219_hw_params,
  216. };
  217. static const struct snd_soc_ops rockchip_sound_dmic_ops = {
  218. .startup = rockchip_sound_startup,
  219. .hw_params = rockchip_sound_dmic_hw_params,
  220. };
  221. static struct snd_soc_card rockchip_sound_card = {
  222. .name = "rk3399-gru-sound",
  223. .owner = THIS_MODULE,
  224. .dapm_widgets = rockchip_dapm_widgets,
  225. .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets),
  226. .controls = rockchip_controls,
  227. .num_controls = ARRAY_SIZE(rockchip_controls),
  228. };
  229. enum {
  230. DAILINK_CDNDP,
  231. DAILINK_DA7219,
  232. DAILINK_DMIC,
  233. DAILINK_MAX98357A,
  234. DAILINK_RT5514,
  235. DAILINK_RT5514_DSP,
  236. };
  237. SND_SOC_DAILINK_DEFS(cdndp,
  238. DAILINK_COMP_ARRAY(COMP_EMPTY()),
  239. DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "spdif-hifi")),
  240. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  241. SND_SOC_DAILINK_DEFS(da7219,
  242. DAILINK_COMP_ARRAY(COMP_EMPTY()),
  243. DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "da7219-hifi")),
  244. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  245. SND_SOC_DAILINK_DEFS(dmic,
  246. DAILINK_COMP_ARRAY(COMP_EMPTY()),
  247. DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "dmic-hifi")),
  248. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  249. SND_SOC_DAILINK_DEFS(max98357a,
  250. DAILINK_COMP_ARRAY(COMP_EMPTY()),
  251. DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "HiFi")),
  252. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  253. SND_SOC_DAILINK_DEFS(rt5514,
  254. DAILINK_COMP_ARRAY(COMP_EMPTY()),
  255. DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5514-aif1")),
  256. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  257. SND_SOC_DAILINK_DEFS(rt5514_dsp,
  258. DAILINK_COMP_ARRAY(COMP_EMPTY()),
  259. DAILINK_COMP_ARRAY(COMP_DUMMY()),
  260. DAILINK_COMP_ARRAY(COMP_EMPTY()));
  261. static const struct snd_soc_dai_link rockchip_dais[] = {
  262. [DAILINK_CDNDP] = {
  263. .name = "DP",
  264. .stream_name = "DP PCM",
  265. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  266. SND_SOC_DAIFMT_CBS_CFS,
  267. SND_SOC_DAILINK_REG(cdndp),
  268. },
  269. [DAILINK_DA7219] = {
  270. .name = "DA7219",
  271. .stream_name = "DA7219 PCM",
  272. .init = rockchip_sound_da7219_init,
  273. .ops = &rockchip_sound_da7219_ops,
  274. /* set da7219 as slave */
  275. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  276. SND_SOC_DAIFMT_CBS_CFS,
  277. SND_SOC_DAILINK_REG(da7219),
  278. },
  279. [DAILINK_DMIC] = {
  280. .name = "DMIC",
  281. .stream_name = "DMIC PCM",
  282. .ops = &rockchip_sound_dmic_ops,
  283. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  284. SND_SOC_DAIFMT_CBS_CFS,
  285. SND_SOC_DAILINK_REG(dmic),
  286. },
  287. [DAILINK_MAX98357A] = {
  288. .name = "MAX98357A",
  289. .stream_name = "MAX98357A PCM",
  290. .ops = &rockchip_sound_max98357a_ops,
  291. /* set max98357a as slave */
  292. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  293. SND_SOC_DAIFMT_CBS_CFS,
  294. SND_SOC_DAILINK_REG(max98357a),
  295. },
  296. [DAILINK_RT5514] = {
  297. .name = "RT5514",
  298. .stream_name = "RT5514 PCM",
  299. .ops = &rockchip_sound_rt5514_ops,
  300. /* set rt5514 as slave */
  301. .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  302. SND_SOC_DAIFMT_CBS_CFS,
  303. SND_SOC_DAILINK_REG(rt5514),
  304. },
  305. /* RT5514 DSP for voice wakeup via spi bus */
  306. [DAILINK_RT5514_DSP] = {
  307. .name = "RT5514 DSP",
  308. .stream_name = "Wake on Voice",
  309. SND_SOC_DAILINK_REG(rt5514_dsp),
  310. },
  311. };
  312. static const struct snd_soc_dapm_route rockchip_sound_cdndp_routes[] = {
  313. /* Output */
  314. {"HDMI", NULL, "TX"},
  315. };
  316. static const struct snd_soc_dapm_route rockchip_sound_da7219_routes[] = {
  317. /* Output */
  318. {"Headphones", NULL, "HPL"},
  319. {"Headphones", NULL, "HPR"},
  320. /* Input */
  321. {"MIC", NULL, "Headset Mic"},
  322. };
  323. static const struct snd_soc_dapm_route rockchip_sound_dmic_routes[] = {
  324. /* Input */
  325. {"DMic", NULL, "Int Mic"},
  326. };
  327. static const struct snd_soc_dapm_route rockchip_sound_max98357a_routes[] = {
  328. /* Output */
  329. {"Speakers", NULL, "Speaker"},
  330. };
  331. static const struct snd_soc_dapm_route rockchip_sound_rt5514_routes[] = {
  332. /* Input */
  333. {"DMIC1L", NULL, "Int Mic"},
  334. {"DMIC1R", NULL, "Int Mic"},
  335. };
  336. struct rockchip_sound_route {
  337. const struct snd_soc_dapm_route *routes;
  338. int num_routes;
  339. };
  340. static const struct rockchip_sound_route rockchip_routes[] = {
  341. [DAILINK_CDNDP] = {
  342. .routes = rockchip_sound_cdndp_routes,
  343. .num_routes = ARRAY_SIZE(rockchip_sound_cdndp_routes),
  344. },
  345. [DAILINK_DA7219] = {
  346. .routes = rockchip_sound_da7219_routes,
  347. .num_routes = ARRAY_SIZE(rockchip_sound_da7219_routes),
  348. },
  349. [DAILINK_DMIC] = {
  350. .routes = rockchip_sound_dmic_routes,
  351. .num_routes = ARRAY_SIZE(rockchip_sound_dmic_routes),
  352. },
  353. [DAILINK_MAX98357A] = {
  354. .routes = rockchip_sound_max98357a_routes,
  355. .num_routes = ARRAY_SIZE(rockchip_sound_max98357a_routes),
  356. },
  357. [DAILINK_RT5514] = {
  358. .routes = rockchip_sound_rt5514_routes,
  359. .num_routes = ARRAY_SIZE(rockchip_sound_rt5514_routes),
  360. },
  361. [DAILINK_RT5514_DSP] = {},
  362. };
  363. struct dailink_match_data {
  364. const char *compatible;
  365. struct bus_type *bus_type;
  366. };
  367. static const struct dailink_match_data dailink_match[] = {
  368. [DAILINK_CDNDP] = {
  369. .compatible = "rockchip,rk3399-cdn-dp",
  370. },
  371. [DAILINK_DA7219] = {
  372. .compatible = "dlg,da7219",
  373. },
  374. [DAILINK_DMIC] = {
  375. .compatible = "dmic-codec",
  376. },
  377. [DAILINK_MAX98357A] = {
  378. .compatible = "maxim,max98357a",
  379. },
  380. [DAILINK_RT5514] = {
  381. .compatible = "realtek,rt5514",
  382. .bus_type = &i2c_bus_type,
  383. },
  384. [DAILINK_RT5514_DSP] = {
  385. .compatible = "realtek,rt5514",
  386. .bus_type = &spi_bus_type,
  387. },
  388. };
  389. static int rockchip_sound_codec_node_match(struct device_node *np_codec)
  390. {
  391. struct device *dev;
  392. int i;
  393. for (i = 0; i < ARRAY_SIZE(dailink_match); i++) {
  394. if (!of_device_is_compatible(np_codec,
  395. dailink_match[i].compatible))
  396. continue;
  397. if (dailink_match[i].bus_type) {
  398. dev = bus_find_device_by_of_node(dailink_match[i].bus_type,
  399. np_codec);
  400. if (!dev)
  401. continue;
  402. put_device(dev);
  403. }
  404. return i;
  405. }
  406. return -1;
  407. }
  408. static int rockchip_sound_of_parse_dais(struct device *dev,
  409. struct snd_soc_card *card)
  410. {
  411. struct device_node *np_cpu, *np_cpu0, *np_cpu1;
  412. struct device_node *np_codec;
  413. struct snd_soc_dai_link *dai;
  414. struct snd_soc_dapm_route *routes;
  415. int i, index;
  416. int num_routes;
  417. card->dai_link = devm_kzalloc(dev, sizeof(rockchip_dais),
  418. GFP_KERNEL);
  419. if (!card->dai_link)
  420. return -ENOMEM;
  421. num_routes = 0;
  422. for (i = 0; i < ARRAY_SIZE(rockchip_routes); i++)
  423. num_routes += rockchip_routes[i].num_routes;
  424. routes = devm_kcalloc(dev, num_routes, sizeof(*routes),
  425. GFP_KERNEL);
  426. if (!routes)
  427. return -ENOMEM;
  428. card->dapm_routes = routes;
  429. np_cpu0 = of_parse_phandle(dev->of_node, "rockchip,cpu", 0);
  430. np_cpu1 = of_parse_phandle(dev->of_node, "rockchip,cpu", 1);
  431. card->num_dapm_routes = 0;
  432. card->num_links = 0;
  433. for (i = 0; i < ARRAY_SIZE(rockchip_dais); i++) {
  434. np_codec = of_parse_phandle(dev->of_node,
  435. "rockchip,codec", i);
  436. if (!np_codec)
  437. break;
  438. if (!of_device_is_available(np_codec))
  439. continue;
  440. index = rockchip_sound_codec_node_match(np_codec);
  441. if (index < 0)
  442. continue;
  443. switch (index) {
  444. case DAILINK_CDNDP:
  445. np_cpu = np_cpu1;
  446. break;
  447. case DAILINK_RT5514_DSP:
  448. np_cpu = np_codec;
  449. break;
  450. default:
  451. np_cpu = np_cpu0;
  452. break;
  453. }
  454. if (!np_cpu) {
  455. dev_err(dev, "Missing 'rockchip,cpu' for %s\n",
  456. rockchip_dais[index].name);
  457. return -EINVAL;
  458. }
  459. dai = &card->dai_link[card->num_links++];
  460. *dai = rockchip_dais[index];
  461. if (!dai->codecs->name)
  462. dai->codecs->of_node = np_codec;
  463. dai->platforms->of_node = np_cpu;
  464. dai->cpus->of_node = np_cpu;
  465. if (card->num_dapm_routes + rockchip_routes[index].num_routes >
  466. num_routes) {
  467. dev_err(dev, "Too many routes\n");
  468. return -EINVAL;
  469. }
  470. memcpy(routes + card->num_dapm_routes,
  471. rockchip_routes[index].routes,
  472. rockchip_routes[index].num_routes * sizeof(*routes));
  473. card->num_dapm_routes += rockchip_routes[index].num_routes;
  474. }
  475. return 0;
  476. }
  477. static int rockchip_sound_probe(struct platform_device *pdev)
  478. {
  479. struct snd_soc_card *card = &rockchip_sound_card;
  480. int ret;
  481. ret = rockchip_sound_of_parse_dais(&pdev->dev, card);
  482. if (ret < 0) {
  483. dev_err(&pdev->dev, "Failed to parse dais: %d\n", ret);
  484. return ret;
  485. }
  486. /* Set DMIC wakeup delay */
  487. ret = device_property_read_u32(&pdev->dev, "dmic-wakeup-delay-ms",
  488. &dmic_wakeup_delay);
  489. if (ret) {
  490. dmic_wakeup_delay = 0;
  491. dev_dbg(&pdev->dev,
  492. "no optional property 'dmic-wakeup-delay-ms' found, default: no delay\n");
  493. }
  494. card->dev = &pdev->dev;
  495. return devm_snd_soc_register_card(&pdev->dev, card);
  496. }
  497. static const struct of_device_id rockchip_sound_of_match[] = {
  498. { .compatible = "rockchip,rk3399-gru-sound", },
  499. {},
  500. };
  501. static struct platform_driver rockchip_sound_driver = {
  502. .probe = rockchip_sound_probe,
  503. .driver = {
  504. .name = DRV_NAME,
  505. .of_match_table = rockchip_sound_of_match,
  506. #ifdef CONFIG_PM
  507. .pm = &snd_soc_pm_ops,
  508. #endif
  509. },
  510. };
  511. module_platform_driver(rockchip_sound_driver);
  512. MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
  513. MODULE_DESCRIPTION("Rockchip ASoC Machine Driver");
  514. MODULE_LICENSE("GPL v2");
  515. MODULE_ALIAS("platform:" DRV_NAME);
  516. MODULE_DEVICE_TABLE(of, rockchip_sound_of_match);