sdm845.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  4. */
  5. #include <dt-bindings/sound/qcom,q6afe.h>
  6. #include <linux/module.h>
  7. #include <linux/platform_device.h>
  8. #include <sound/core.h>
  9. #include <sound/pcm.h>
  10. #include <sound/pcm_params.h>
  11. #include <sound/jack.h>
  12. #include <sound/soc.h>
  13. #include <linux/soundwire/sdw.h>
  14. #include <uapi/linux/input-event-codes.h>
  15. #include "common.h"
  16. #include "qdsp6/q6afe.h"
  17. #include "sdw.h"
  18. #include "../codecs/rt5663.h"
  19. #define DRIVER_NAME "sdm845"
  20. #define DEFAULT_SAMPLE_RATE_48K 48000
  21. #define DEFAULT_MCLK_RATE 24576000
  22. #define TDM_BCLK_RATE 6144000
  23. #define MI2S_BCLK_RATE 1536000
  24. #define LEFT_SPK_TDM_TX_MASK 0x30
  25. #define RIGHT_SPK_TDM_TX_MASK 0xC0
  26. #define SPK_TDM_RX_MASK 0x03
  27. #define NUM_TDM_SLOTS 8
  28. #define SLIM_MAX_TX_PORTS 16
  29. #define SLIM_MAX_RX_PORTS 13
  30. #define WCD934X_DEFAULT_MCLK_RATE 9600000
  31. struct sdm845_snd_data {
  32. struct snd_soc_jack jack;
  33. bool jack_setup;
  34. bool slim_port_setup;
  35. bool stream_prepared[AFE_PORT_MAX];
  36. struct snd_soc_card *card;
  37. uint32_t pri_mi2s_clk_count;
  38. uint32_t sec_mi2s_clk_count;
  39. uint32_t quat_tdm_clk_count;
  40. struct sdw_stream_runtime *sruntime[AFE_PORT_MAX];
  41. };
  42. static struct snd_soc_jack_pin sdm845_jack_pins[] = {
  43. {
  44. .pin = "Headphone Jack",
  45. .mask = SND_JACK_HEADPHONE,
  46. },
  47. {
  48. .pin = "Headset Mic",
  49. .mask = SND_JACK_MICROPHONE,
  50. },
  51. };
  52. static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
  53. static int sdm845_slim_snd_hw_params(struct snd_pcm_substream *substream,
  54. struct snd_pcm_hw_params *params)
  55. {
  56. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  57. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  58. struct snd_soc_dai *codec_dai;
  59. struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
  60. u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
  61. struct sdw_stream_runtime *sruntime;
  62. u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
  63. int ret = 0, i;
  64. for_each_rtd_codec_dais(rtd, i, codec_dai) {
  65. sruntime = snd_soc_dai_get_stream(codec_dai,
  66. substream->stream);
  67. if (sruntime != ERR_PTR(-ENOTSUPP))
  68. pdata->sruntime[cpu_dai->id] = sruntime;
  69. ret = snd_soc_dai_get_channel_map(codec_dai,
  70. &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
  71. if (ret != 0 && ret != -ENOTSUPP) {
  72. pr_err("failed to get codec chan map, err:%d\n", ret);
  73. return ret;
  74. } else if (ret == -ENOTSUPP) {
  75. /* Ignore unsupported */
  76. continue;
  77. }
  78. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  79. ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
  80. rx_ch_cnt, rx_ch);
  81. else
  82. ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt,
  83. tx_ch, 0, NULL);
  84. if (ret != 0 && ret != -ENOTSUPP) {
  85. dev_err(rtd->dev, "failed to set cpu chan map, err:%d\n", ret);
  86. return ret;
  87. }
  88. }
  89. return 0;
  90. }
  91. static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
  92. struct snd_pcm_hw_params *params)
  93. {
  94. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  95. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  96. struct snd_soc_dai *codec_dai;
  97. int ret = 0, j;
  98. int channels, slot_width;
  99. switch (params_format(params)) {
  100. case SNDRV_PCM_FORMAT_S16_LE:
  101. slot_width = 16;
  102. break;
  103. default:
  104. dev_err(rtd->dev, "%s: invalid param format 0x%x\n",
  105. __func__, params_format(params));
  106. return -EINVAL;
  107. }
  108. channels = params_channels(params);
  109. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  110. ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x3,
  111. 8, slot_width);
  112. if (ret < 0) {
  113. dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
  114. __func__, ret);
  115. goto end;
  116. }
  117. ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
  118. channels, tdm_slot_offset);
  119. if (ret < 0) {
  120. dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
  121. __func__, ret);
  122. goto end;
  123. }
  124. } else {
  125. ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0,
  126. 8, slot_width);
  127. if (ret < 0) {
  128. dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
  129. __func__, ret);
  130. goto end;
  131. }
  132. ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
  133. tdm_slot_offset, 0, NULL);
  134. if (ret < 0) {
  135. dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
  136. __func__, ret);
  137. goto end;
  138. }
  139. }
  140. for_each_rtd_codec_dais(rtd, j, codec_dai) {
  141. if (!strcmp(codec_dai->component->name_prefix, "Left")) {
  142. ret = snd_soc_dai_set_tdm_slot(
  143. codec_dai, LEFT_SPK_TDM_TX_MASK,
  144. SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
  145. slot_width);
  146. if (ret < 0) {
  147. dev_err(rtd->dev,
  148. "DEV0 TDM slot err:%d\n", ret);
  149. return ret;
  150. }
  151. }
  152. if (!strcmp(codec_dai->component->name_prefix, "Right")) {
  153. ret = snd_soc_dai_set_tdm_slot(
  154. codec_dai, RIGHT_SPK_TDM_TX_MASK,
  155. SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
  156. slot_width);
  157. if (ret < 0) {
  158. dev_err(rtd->dev,
  159. "DEV1 TDM slot err:%d\n", ret);
  160. return ret;
  161. }
  162. }
  163. }
  164. end:
  165. return ret;
  166. }
  167. static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
  168. struct snd_pcm_hw_params *params)
  169. {
  170. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  171. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  172. struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
  173. int ret = 0;
  174. switch (cpu_dai->id) {
  175. case PRIMARY_MI2S_RX:
  176. case PRIMARY_MI2S_TX:
  177. /*
  178. * Use ASRC for internal clocks, as PLL rate isn't multiple
  179. * of BCLK.
  180. */
  181. rt5663_sel_asrc_clk_src(
  182. codec_dai->component,
  183. RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
  184. RT5663_CLK_SEL_I2S1_ASRC);
  185. ret = snd_soc_dai_set_sysclk(
  186. codec_dai, RT5663_SCLK_S_MCLK, DEFAULT_MCLK_RATE,
  187. SND_SOC_CLOCK_IN);
  188. if (ret < 0)
  189. dev_err(rtd->dev,
  190. "snd_soc_dai_set_sysclk err = %d\n", ret);
  191. break;
  192. case QUATERNARY_TDM_RX_0:
  193. case QUATERNARY_TDM_TX_0:
  194. ret = sdm845_tdm_snd_hw_params(substream, params);
  195. break;
  196. case SLIMBUS_0_RX...SLIMBUS_6_TX:
  197. ret = sdm845_slim_snd_hw_params(substream, params);
  198. break;
  199. case QUATERNARY_MI2S_RX:
  200. break;
  201. default:
  202. pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
  203. break;
  204. }
  205. return ret;
  206. }
  207. static void sdm845_jack_free(struct snd_jack *jack)
  208. {
  209. struct snd_soc_component *component = jack->private_data;
  210. snd_soc_component_set_jack(component, NULL, NULL);
  211. }
  212. static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
  213. {
  214. struct snd_soc_component *component;
  215. struct snd_soc_card *card = rtd->card;
  216. struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
  217. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  218. struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
  219. struct snd_soc_dai_link *link = rtd->dai_link;
  220. struct snd_jack *jack;
  221. /*
  222. * Codec SLIMBUS configuration
  223. * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
  224. * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
  225. * TX14, TX15, TX16
  226. */
  227. unsigned int rx_ch[SLIM_MAX_RX_PORTS] = {144, 145, 146, 147, 148, 149,
  228. 150, 151, 152, 153, 154, 155, 156};
  229. unsigned int tx_ch[SLIM_MAX_TX_PORTS] = {128, 129, 130, 131, 132, 133,
  230. 134, 135, 136, 137, 138, 139,
  231. 140, 141, 142, 143};
  232. int rval, i;
  233. if (!pdata->jack_setup) {
  234. rval = snd_soc_card_jack_new_pins(card, "Headset Jack",
  235. SND_JACK_HEADSET |
  236. SND_JACK_HEADPHONE |
  237. SND_JACK_BTN_0 | SND_JACK_BTN_1 |
  238. SND_JACK_BTN_2 | SND_JACK_BTN_3,
  239. &pdata->jack,
  240. sdm845_jack_pins,
  241. ARRAY_SIZE(sdm845_jack_pins));
  242. if (rval < 0) {
  243. dev_err(card->dev, "Unable to add Headphone Jack\n");
  244. return rval;
  245. }
  246. jack = pdata->jack.jack;
  247. snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
  248. snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
  249. snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
  250. snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
  251. pdata->jack_setup = true;
  252. }
  253. switch (cpu_dai->id) {
  254. case PRIMARY_MI2S_RX:
  255. jack = pdata->jack.jack;
  256. component = codec_dai->component;
  257. jack->private_data = component;
  258. jack->private_free = sdm845_jack_free;
  259. rval = snd_soc_component_set_jack(component,
  260. &pdata->jack, NULL);
  261. if (rval != 0 && rval != -ENOTSUPP) {
  262. dev_warn(card->dev, "Failed to set jack: %d\n", rval);
  263. return rval;
  264. }
  265. break;
  266. case SLIMBUS_0_RX...SLIMBUS_6_TX:
  267. /* setting up wcd multiple times for slim port is redundant */
  268. if (pdata->slim_port_setup || !link->no_pcm)
  269. return 0;
  270. for_each_rtd_codec_dais(rtd, i, codec_dai) {
  271. rval = snd_soc_dai_set_channel_map(codec_dai,
  272. ARRAY_SIZE(tx_ch),
  273. tx_ch,
  274. ARRAY_SIZE(rx_ch),
  275. rx_ch);
  276. if (rval != 0 && rval != -ENOTSUPP)
  277. return rval;
  278. snd_soc_dai_set_sysclk(codec_dai, 0,
  279. WCD934X_DEFAULT_MCLK_RATE,
  280. SNDRV_PCM_STREAM_PLAYBACK);
  281. rval = snd_soc_component_set_jack(codec_dai->component,
  282. &pdata->jack, NULL);
  283. if (rval != 0 && rval != -ENOTSUPP) {
  284. dev_warn(card->dev, "Failed to set jack: %d\n", rval);
  285. return rval;
  286. }
  287. }
  288. pdata->slim_port_setup = true;
  289. break;
  290. default:
  291. break;
  292. }
  293. return 0;
  294. }
  295. static int sdm845_snd_startup(struct snd_pcm_substream *substream)
  296. {
  297. unsigned int fmt = SND_SOC_DAIFMT_BP_FP;
  298. unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC;
  299. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  300. struct snd_soc_card *card = rtd->card;
  301. struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
  302. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  303. struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
  304. int j;
  305. int ret;
  306. switch (cpu_dai->id) {
  307. case PRIMARY_MI2S_RX:
  308. case PRIMARY_MI2S_TX:
  309. codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF;
  310. if (++(data->pri_mi2s_clk_count) == 1) {
  311. snd_soc_dai_set_sysclk(cpu_dai,
  312. Q6AFE_LPASS_CLK_ID_MCLK_1,
  313. DEFAULT_MCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
  314. snd_soc_dai_set_sysclk(cpu_dai,
  315. Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
  316. MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
  317. }
  318. snd_soc_dai_set_fmt(cpu_dai, fmt);
  319. snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
  320. break;
  321. case SECONDARY_MI2S_TX:
  322. codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
  323. if (++(data->sec_mi2s_clk_count) == 1) {
  324. snd_soc_dai_set_sysclk(cpu_dai,
  325. Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
  326. MI2S_BCLK_RATE, SNDRV_PCM_STREAM_CAPTURE);
  327. }
  328. snd_soc_dai_set_fmt(cpu_dai, fmt);
  329. snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
  330. break;
  331. case QUATERNARY_MI2S_RX:
  332. snd_soc_dai_set_sysclk(cpu_dai,
  333. Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
  334. MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
  335. snd_soc_dai_set_fmt(cpu_dai, fmt);
  336. break;
  337. case QUATERNARY_TDM_RX_0:
  338. case QUATERNARY_TDM_TX_0:
  339. if (++(data->quat_tdm_clk_count) == 1) {
  340. snd_soc_dai_set_sysclk(cpu_dai,
  341. Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
  342. TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
  343. }
  344. codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
  345. for_each_rtd_codec_dais(rtd, j, codec_dai) {
  346. if (!strcmp(codec_dai->component->name_prefix,
  347. "Left")) {
  348. ret = snd_soc_dai_set_fmt(
  349. codec_dai, codec_dai_fmt);
  350. if (ret < 0) {
  351. dev_err(rtd->dev,
  352. "Left TDM fmt err:%d\n", ret);
  353. return ret;
  354. }
  355. }
  356. if (!strcmp(codec_dai->component->name_prefix,
  357. "Right")) {
  358. ret = snd_soc_dai_set_fmt(
  359. codec_dai, codec_dai_fmt);
  360. if (ret < 0) {
  361. dev_err(rtd->dev,
  362. "Right TDM slot err:%d\n", ret);
  363. return ret;
  364. }
  365. }
  366. }
  367. break;
  368. case SLIMBUS_0_RX...SLIMBUS_6_TX:
  369. break;
  370. default:
  371. pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
  372. break;
  373. }
  374. return qcom_snd_sdw_startup(substream);
  375. }
  376. static void sdm845_snd_shutdown(struct snd_pcm_substream *substream)
  377. {
  378. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  379. struct snd_soc_card *card = rtd->card;
  380. struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
  381. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  382. struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
  383. switch (cpu_dai->id) {
  384. case PRIMARY_MI2S_RX:
  385. case PRIMARY_MI2S_TX:
  386. if (--(data->pri_mi2s_clk_count) == 0) {
  387. snd_soc_dai_set_sysclk(cpu_dai,
  388. Q6AFE_LPASS_CLK_ID_MCLK_1,
  389. 0, SNDRV_PCM_STREAM_PLAYBACK);
  390. snd_soc_dai_set_sysclk(cpu_dai,
  391. Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
  392. 0, SNDRV_PCM_STREAM_PLAYBACK);
  393. }
  394. break;
  395. case SECONDARY_MI2S_TX:
  396. if (--(data->sec_mi2s_clk_count) == 0) {
  397. snd_soc_dai_set_sysclk(cpu_dai,
  398. Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
  399. 0, SNDRV_PCM_STREAM_CAPTURE);
  400. }
  401. break;
  402. case QUATERNARY_TDM_RX_0:
  403. case QUATERNARY_TDM_TX_0:
  404. if (--(data->quat_tdm_clk_count) == 0) {
  405. snd_soc_dai_set_sysclk(cpu_dai,
  406. Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
  407. 0, SNDRV_PCM_STREAM_PLAYBACK);
  408. }
  409. break;
  410. case SLIMBUS_0_RX...SLIMBUS_6_TX:
  411. case QUATERNARY_MI2S_RX:
  412. break;
  413. default:
  414. pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
  415. break;
  416. }
  417. data->sruntime[cpu_dai->id] = NULL;
  418. sdw_release_stream(sruntime);
  419. }
  420. static int sdm845_snd_prepare(struct snd_pcm_substream *substream)
  421. {
  422. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  423. struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
  424. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  425. struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
  426. int ret;
  427. if (!sruntime)
  428. return 0;
  429. if (data->stream_prepared[cpu_dai->id]) {
  430. sdw_disable_stream(sruntime);
  431. sdw_deprepare_stream(sruntime);
  432. data->stream_prepared[cpu_dai->id] = false;
  433. }
  434. ret = sdw_prepare_stream(sruntime);
  435. if (ret)
  436. return ret;
  437. /**
  438. * NOTE: there is a strict hw requirement about the ordering of port
  439. * enables and actual WSA881x PA enable. PA enable should only happen
  440. * after soundwire ports are enabled if not DC on the line is
  441. * accumulated resulting in Click/Pop Noise
  442. * PA enable/mute are handled as part of codec DAPM and digital mute.
  443. */
  444. ret = sdw_enable_stream(sruntime);
  445. if (ret) {
  446. sdw_deprepare_stream(sruntime);
  447. return ret;
  448. }
  449. data->stream_prepared[cpu_dai->id] = true;
  450. return ret;
  451. }
  452. static int sdm845_snd_hw_free(struct snd_pcm_substream *substream)
  453. {
  454. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  455. struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
  456. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  457. struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
  458. if (sruntime && data->stream_prepared[cpu_dai->id]) {
  459. sdw_disable_stream(sruntime);
  460. sdw_deprepare_stream(sruntime);
  461. data->stream_prepared[cpu_dai->id] = false;
  462. }
  463. return 0;
  464. }
  465. static const struct snd_soc_ops sdm845_be_ops = {
  466. .hw_params = sdm845_snd_hw_params,
  467. .hw_free = sdm845_snd_hw_free,
  468. .prepare = sdm845_snd_prepare,
  469. .startup = sdm845_snd_startup,
  470. .shutdown = sdm845_snd_shutdown,
  471. };
  472. static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  473. struct snd_pcm_hw_params *params)
  474. {
  475. struct snd_interval *rate = hw_param_interval(params,
  476. SNDRV_PCM_HW_PARAM_RATE);
  477. struct snd_interval *channels = hw_param_interval(params,
  478. SNDRV_PCM_HW_PARAM_CHANNELS);
  479. struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
  480. rate->min = rate->max = DEFAULT_SAMPLE_RATE_48K;
  481. channels->min = channels->max = 2;
  482. snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
  483. return 0;
  484. }
  485. static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
  486. SND_SOC_DAPM_HP("Headphone Jack", NULL),
  487. SND_SOC_DAPM_MIC("Headset Mic", NULL),
  488. SND_SOC_DAPM_SPK("Left Spk", NULL),
  489. SND_SOC_DAPM_SPK("Right Spk", NULL),
  490. SND_SOC_DAPM_MIC("Int Mic", NULL),
  491. };
  492. static const struct snd_kcontrol_new sdm845_snd_controls[] = {
  493. SOC_DAPM_PIN_SWITCH("Headphone Jack"),
  494. SOC_DAPM_PIN_SWITCH("Headset Mic"),
  495. };
  496. static void sdm845_add_ops(struct snd_soc_card *card)
  497. {
  498. struct snd_soc_dai_link *link;
  499. int i;
  500. for_each_card_prelinks(card, i, link) {
  501. if (link->no_pcm == 1) {
  502. link->ops = &sdm845_be_ops;
  503. link->be_hw_params_fixup = sdm845_be_hw_params_fixup;
  504. }
  505. link->init = sdm845_dai_init;
  506. }
  507. }
  508. static int sdm845_snd_platform_probe(struct platform_device *pdev)
  509. {
  510. struct snd_soc_card *card;
  511. struct sdm845_snd_data *data;
  512. struct device *dev = &pdev->dev;
  513. int ret;
  514. card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
  515. if (!card)
  516. return -ENOMEM;
  517. /* Allocate the private data */
  518. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  519. if (!data)
  520. return -ENOMEM;
  521. card->driver_name = DRIVER_NAME;
  522. card->dapm_widgets = sdm845_snd_widgets;
  523. card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
  524. card->controls = sdm845_snd_controls;
  525. card->num_controls = ARRAY_SIZE(sdm845_snd_controls);
  526. card->dev = dev;
  527. card->owner = THIS_MODULE;
  528. dev_set_drvdata(dev, card);
  529. ret = qcom_snd_parse_of(card);
  530. if (ret)
  531. return ret;
  532. data->card = card;
  533. snd_soc_card_set_drvdata(card, data);
  534. sdm845_add_ops(card);
  535. return devm_snd_soc_register_card(dev, card);
  536. }
  537. static const struct of_device_id sdm845_snd_device_id[] = {
  538. { .compatible = "qcom,sdm845-sndcard" },
  539. /* Do not grow the list for compatible devices */
  540. { .compatible = "qcom,db845c-sndcard" },
  541. { .compatible = "lenovo,yoga-c630-sndcard" },
  542. {},
  543. };
  544. MODULE_DEVICE_TABLE(of, sdm845_snd_device_id);
  545. static struct platform_driver sdm845_snd_driver = {
  546. .probe = sdm845_snd_platform_probe,
  547. .driver = {
  548. .name = "msm-snd-sdm845",
  549. .of_match_table = sdm845_snd_device_id,
  550. },
  551. };
  552. module_platform_driver(sdm845_snd_driver);
  553. MODULE_DESCRIPTION("sdm845 ASoC Machine Driver");
  554. MODULE_LICENSE("GPL");