msm_common.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. /* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/gpio.h>
  13. #include <linux/of_gpio.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/slab.h>
  16. #include <linux/of_device.h>
  17. #include <sound/control.h>
  18. #include <sound/core.h>
  19. #include <sound/soc.h>
  20. #include <sound/pcm_params.h>
  21. #include <asoc/msm-cdc-pinctrl.h>
  22. #include <dsp/spf-core.h>
  23. #include <dsp/msm_audio_ion.h>
  24. #include <sound/info.h>
  25. #include <dsp/audio_prm.h>
  26. #include "msm_common.h"
  27. struct snd_card_pdata {
  28. struct kobject snd_card_kobj;
  29. int card_status;
  30. }*snd_card_pdata;
  31. #define to_asoc_mach_common_pdata(kobj) \
  32. container_of((kobj), struct msm_common_pdata, aud_dev_kobj)
  33. #define DEVICE_ENABLE 1
  34. #define DEVICE_DISABLE 0
  35. #define ARRAY_SZ 21
  36. #define BUF_SZ 32
  37. #define DIR_SZ 10
  38. #define MAX_CODEC_DAI 8
  39. #define TDM_SLOT_WIDTH_BITS 32
  40. #define TDM_MAX_SLOTS 8
  41. #define MI2S_NUM_CHANNELS 2
  42. static struct attribute device_state_attr = {
  43. .name = "state",
  44. .mode = 0660,
  45. };
  46. static struct attribute card_state_attr = {
  47. .name = "card_state",
  48. .mode = 0660,
  49. };
  50. #define MAX_PORT 20
  51. #define CODEC_CHMAP "Channel Map"
  52. enum backend_id {
  53. SLIM = 1,
  54. CODEC_DMA,
  55. };
  56. struct chmap_pdata {
  57. int id;
  58. uint32_t num_codec_dai;
  59. struct snd_soc_dai *dai[MAX_CODEC_DAI];
  60. };
  61. #define MAX_USR_INPUT 10
  62. static ssize_t aud_dev_sysfs_store(struct kobject *kobj,
  63. struct attribute *attr,
  64. const char *buf, size_t count)
  65. {
  66. ssize_t ret = -EINVAL;
  67. struct msm_common_pdata *pdata = to_asoc_mach_common_pdata(kobj);
  68. uint32_t pcm_id, state = 0;
  69. if (count > MAX_USR_INPUT) {
  70. pr_err("%s: invalid string written", __func__);
  71. goto done;
  72. }
  73. sscanf(buf, "%d %d", &pcm_id, &state);
  74. if ((pcm_id > pdata->num_aud_devs) || (pcm_id < 0)) {
  75. pr_err("%s: invalid pcm id %d \n", __func__, pcm_id);
  76. goto done;
  77. }
  78. if ((state > DEVICE_ENABLE) || (state < DEVICE_DISABLE)) {
  79. pr_err("%s: invalid state %d \n", __func__, state);
  80. goto done;
  81. }
  82. pr_debug("%s: pcm_id %d state %d \n", __func__, pcm_id, state);
  83. pdata->aud_dev_state[pcm_id] = state;
  84. if ( state == DEVICE_ENABLE && (pdata->dsp_sessions_closed != 0))
  85. pdata->dsp_sessions_closed = 0;
  86. ret = count;
  87. done:
  88. return ret;
  89. }
  90. static const struct sysfs_ops aud_dev_sysfs_ops = {
  91. .store = aud_dev_sysfs_store,
  92. };
  93. static struct kobj_type aud_dev_ktype = {
  94. .sysfs_ops = &aud_dev_sysfs_ops,
  95. };
  96. static int aud_dev_sysfs_init(struct msm_common_pdata *pdata)
  97. {
  98. int ret = 0;
  99. char dir[10] = "aud_dev";
  100. ret = kobject_init_and_add(&pdata->aud_dev_kobj, &aud_dev_ktype,
  101. kernel_kobj, dir);
  102. if (ret < 0) {
  103. pr_err("%s: Failed to add kobject %s, err = %d\n",
  104. __func__, dir, ret);
  105. goto done;
  106. }
  107. ret = sysfs_create_file(&pdata->aud_dev_kobj, &device_state_attr);
  108. if (ret < 0) {
  109. pr_err("%s: Failed to add wdsp_boot sysfs entry to %s\n",
  110. __func__, dir);
  111. goto fail_create_file;
  112. }
  113. return ret;
  114. fail_create_file:
  115. kobject_put(&pdata->aud_dev_kobj);
  116. done:
  117. return ret;
  118. }
  119. int snd_card_notify_user(int card_status)
  120. {
  121. snd_card_pdata->card_status = card_status;
  122. sysfs_notify(&snd_card_pdata->snd_card_kobj, NULL, "card_state");
  123. return 0;
  124. }
  125. static ssize_t snd_card_sysfs_show(struct kobject *kobj,
  126. struct attribute *attr, char *buf)
  127. {
  128. return snprintf(buf, BUF_SZ, "%d", snd_card_pdata->card_status);
  129. }
  130. static ssize_t snd_card_sysfs_store(struct kobject *kobj,
  131. struct attribute *attr, const char *buf, size_t count)
  132. {
  133. sscanf(buf, "%d", &snd_card_pdata->card_status);
  134. sysfs_notify(&snd_card_pdata->snd_card_kobj, NULL, "card_state");
  135. return 0;
  136. }
  137. static const struct sysfs_ops snd_card_sysfs_ops = {
  138. .show = snd_card_sysfs_show,
  139. .store = snd_card_sysfs_store,
  140. };
  141. static struct kobj_type snd_card_ktype = {
  142. .sysfs_ops = &snd_card_sysfs_ops,
  143. };
  144. int snd_card_sysfs_init(void)
  145. {
  146. int ret = 0;
  147. char dir[DIR_SZ] = "snd_card";
  148. snd_card_pdata = kcalloc(1, sizeof(struct snd_card_pdata), GFP_KERNEL);
  149. ret = kobject_init_and_add(&snd_card_pdata->snd_card_kobj, &snd_card_ktype,
  150. kernel_kobj, dir);
  151. if (ret < 0) {
  152. pr_err("%s: Failed to add kobject %s, err = %d\n",
  153. __func__, dir, ret);
  154. goto done;
  155. }
  156. ret = sysfs_create_file(&snd_card_pdata->snd_card_kobj, &card_state_attr);
  157. if (ret < 0) {
  158. pr_err("%s: Failed to add snd_card sysfs entry to %s\n",
  159. __func__, dir);
  160. goto fail_create_file;
  161. }
  162. return ret;
  163. fail_create_file:
  164. kobject_put(&snd_card_pdata->snd_card_kobj);
  165. done:
  166. return ret;
  167. }
  168. static void check_userspace_service_state(struct snd_soc_pcm_runtime *rtd,
  169. struct msm_common_pdata *pdata)
  170. {
  171. dev_info(rtd->card->dev,"%s: pcm_id %d state %d\n", __func__,
  172. rtd->num, pdata->aud_dev_state[rtd->num]);
  173. if (pdata->aud_dev_state[rtd->num] == DEVICE_ENABLE) {
  174. dev_info(rtd->card->dev, "%s userspace service crashed\n",
  175. __func__);
  176. if (pdata->dsp_sessions_closed == 0) {
  177. /*Issue close all graph cmd to DSP*/
  178. spf_core_apm_close_all();
  179. /*unmap all dma mapped buffers*/
  180. msm_audio_ion_crash_handler();
  181. pdata->dsp_sessions_closed = 1;
  182. }
  183. /*Reset the state as sysfs node wont be triggred*/
  184. pdata->aud_dev_state[rtd->num] = 0;
  185. }
  186. }
  187. static int get_intf_index(const char *stream_name)
  188. {
  189. if (strnstr(stream_name, "LPAIF_RXTX", strlen(stream_name)))
  190. return QUAT_MI2S_TDM_AUXPCM;
  191. else if (strnstr(stream_name, "LPAIF_WSA", strlen(stream_name)))
  192. return SEN_MI2S_TDM_AUXPCM;
  193. else if (strnstr(stream_name, "LPAIF_VA", strlen(stream_name)))
  194. return QUIN_MI2S_TDM_AUXPCM;
  195. else if (strnstr(stream_name, "LPAIF_AUD", strlen(stream_name)))
  196. return SEC_MI2S_TDM_AUXPCM;
  197. else if (strnstr(stream_name, "LPAIF", strlen(stream_name))) {
  198. if (strnstr(stream_name, "PRIMARY", strlen(stream_name)))
  199. return PRI_MI2S_TDM_AUXPCM;
  200. else if (strnstr(stream_name, "TERTIARY", strlen(stream_name)))
  201. return TER_MI2S_TDM_AUXPCM;
  202. }
  203. pr_debug("%s: stream name %s does not match\n", __func__, stream_name);
  204. return -EINVAL;
  205. }
  206. static int get_mi2s_clk_id(int index)
  207. {
  208. int clk_id;
  209. switch(index) {
  210. case PRI_MI2S_TDM_AUXPCM:
  211. clk_id = CLOCK_ID_PRI_MI2S_IBIT;
  212. break;
  213. case SEC_MI2S_TDM_AUXPCM:
  214. clk_id = CLOCK_ID_SEP_MI2S_IBIT;
  215. break;
  216. case TER_MI2S_TDM_AUXPCM:
  217. clk_id = CLOCK_ID_TER_MI2S_IBIT;
  218. break;
  219. case QUAT_MI2S_TDM_AUXPCM:
  220. clk_id = CLOCK_ID_QUAD_MI2S_IBIT;
  221. break;
  222. case QUIN_MI2S_TDM_AUXPCM:
  223. clk_id = CLOCK_ID_QUI_MI2S_IBIT;
  224. break;
  225. case SEN_MI2S_TDM_AUXPCM:
  226. clk_id = CLOCK_ID_SEN_MI2S_IBIT;
  227. break;
  228. default:
  229. pr_err("%s: Invalid interface index: %d\n", __func__, index);
  230. clk_id = -EINVAL;
  231. }
  232. pr_debug("%s: clk id: %d\n", __func__, clk_id);
  233. return clk_id;
  234. }
  235. static int get_tdm_clk_id(int index)
  236. {
  237. int clk_id;
  238. switch(index) {
  239. case PRI_MI2S_TDM_AUXPCM:
  240. clk_id = CLOCK_ID_PRI_TDM_IBIT;
  241. break;
  242. case SEC_MI2S_TDM_AUXPCM:
  243. clk_id = CLOCK_ID_SEP_TDM_IBIT;
  244. break;
  245. case TER_MI2S_TDM_AUXPCM:
  246. clk_id = CLOCK_ID_TER_TDM_IBIT;
  247. break;
  248. case QUAT_MI2S_TDM_AUXPCM:
  249. clk_id = CLOCK_ID_QUAD_TDM_IBIT;
  250. break;
  251. case QUIN_MI2S_TDM_AUXPCM:
  252. clk_id = CLOCK_ID_QUI_TDM_IBIT;
  253. break;
  254. case SEN_MI2S_TDM_AUXPCM:
  255. clk_id = CLOCK_ID_SEN_TDM_IBIT;
  256. break;
  257. default:
  258. pr_err("%s: Invalid interface index: %d\n", __func__, index);
  259. clk_id = -EINVAL;
  260. }
  261. pr_debug("%s: clk id: %d\n", __func__, clk_id);
  262. return clk_id;
  263. }
  264. int msm_common_snd_hw_params(struct snd_pcm_substream *substream,
  265. struct snd_pcm_hw_params *params)
  266. {
  267. int ret = 0;
  268. int slot_width = TDM_SLOT_WIDTH_BITS;
  269. int slots;
  270. int sample_width;
  271. unsigned int rate;
  272. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  273. const char *stream_name = rtd->dai_link->stream_name;
  274. struct snd_soc_card *card = rtd->card;
  275. struct msm_common_pdata *pdata = msm_common_get_pdata(card);
  276. int index = get_intf_index(stream_name);
  277. struct clk_cfg intf_clk_cfg;
  278. dev_dbg(rtd->card->dev,
  279. "%s: substream = %s stream = %d\n",
  280. __func__, substream->name, substream->stream);
  281. if (!pdata) {
  282. dev_err(rtd->card->dev, "%s: pdata is NULL\n", __func__);
  283. return -EINVAL;
  284. }
  285. if (index >= 0) {
  286. mutex_lock(&pdata->lock[index]);
  287. if (pdata->mi2s_gpio_p[index]) {
  288. if ((strnstr(stream_name, "TDM", strlen(stream_name)))) {
  289. slots = pdata->tdm_max_slots;
  290. rate = params_rate(params);
  291. intf_clk_cfg.clk_id = get_tdm_clk_id(index);
  292. if (intf_clk_cfg.clk_id < 0) {
  293. ret = -EINVAL;
  294. pr_err("%s: Invalid tdm clk id %d", __func__,
  295. intf_clk_cfg.clk_id);
  296. goto done;
  297. }
  298. intf_clk_cfg.clk_freq_in_hz = rate * slot_width * slots;
  299. intf_clk_cfg.clk_attri = CLOCK_ATTRIBUTE_COUPLE_NO;
  300. intf_clk_cfg.clk_root = 0;
  301. pr_debug("%s: clk_id :%d clk freq %d\n", __func__,
  302. intf_clk_cfg.clk_id, intf_clk_cfg.clk_freq_in_hz);
  303. ret = audio_prm_set_lpass_clk_cfg(&intf_clk_cfg, 1);
  304. if (ret < 0) {
  305. pr_err("%s: prm lpass clk cfg set failed ret %d\n",
  306. __func__, ret);
  307. goto done;
  308. }
  309. } else if ((strnstr(stream_name, "MI2S", strlen(stream_name)))) {
  310. intf_clk_cfg.clk_id = get_mi2s_clk_id(index);
  311. if (intf_clk_cfg.clk_id < 0) {
  312. ret = -EINVAL;
  313. pr_err("%s: Invalid mi2s clk id %d", __func__,
  314. intf_clk_cfg.clk_id);
  315. goto done;
  316. }
  317. rate = params_rate(params);
  318. switch (params_format(params)) {
  319. case SNDRV_PCM_FORMAT_S24_LE:
  320. case SNDRV_PCM_FORMAT_S24_3LE:
  321. case SNDRV_PCM_FORMAT_S32_LE:
  322. sample_width = 32;
  323. break;
  324. case SNDRV_PCM_FORMAT_S16_LE:
  325. default:
  326. sample_width = 16;
  327. pr_debug("%s: bitwidth set to default : %d\n",
  328. __func__, sample_width);
  329. }
  330. intf_clk_cfg.clk_freq_in_hz = rate *
  331. MI2S_NUM_CHANNELS * sample_width;
  332. intf_clk_cfg.clk_attri = CLOCK_ATTRIBUTE_COUPLE_NO;
  333. intf_clk_cfg.clk_root = CLOCK_ROOT_DEFAULT;
  334. pr_debug("%s: mi2s clk_id :%d clk freq %d\n", __func__,
  335. intf_clk_cfg.clk_id, intf_clk_cfg.clk_freq_in_hz);
  336. ret = audio_prm_set_lpass_clk_cfg(&intf_clk_cfg, 1);
  337. if (ret < 0) {
  338. pr_err("%s: prm lpass mi2s clk cfg set failed ret %d\n",
  339. __func__, ret);
  340. goto done;
  341. }
  342. } else {
  343. pr_err("%s: invalid stream name: %s\n", __func__,
  344. stream_name);
  345. }
  346. }
  347. done:
  348. mutex_unlock(&pdata->lock[index]);
  349. }
  350. return ret;
  351. }
  352. int msm_common_snd_startup(struct snd_pcm_substream *substream)
  353. {
  354. int ret = 0;
  355. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  356. struct snd_soc_card *card = rtd->card;
  357. struct msm_common_pdata *pdata = msm_common_get_pdata(card);
  358. const char *stream_name = rtd->dai_link->stream_name;
  359. int index = get_intf_index(stream_name);
  360. dev_dbg(rtd->card->dev,
  361. "%s: substream = %s stream = %d\n",
  362. __func__, substream->name, substream->stream);
  363. if (!pdata) {
  364. dev_err(rtd->card->dev, "%s: pdata is NULL\n", __func__);
  365. return -EINVAL;
  366. }
  367. if (index >= 0) {
  368. mutex_lock(&pdata->lock[index]);
  369. if (pdata->mi2s_gpio_p[index]) {
  370. if (atomic_read(&(pdata->mi2s_gpio_ref_cnt[index])) == 0) {
  371. ret = msm_cdc_pinctrl_select_active_state(
  372. pdata->mi2s_gpio_p[index]);
  373. if (ret) {
  374. pr_err("%s:pinctrl set actve fail with %d\n",
  375. __func__, ret);
  376. goto done;
  377. }
  378. }
  379. atomic_inc(&(pdata->mi2s_gpio_ref_cnt[index]));
  380. }
  381. done:
  382. mutex_unlock(&pdata->lock[index]);
  383. }
  384. return ret;
  385. }
  386. void msm_common_snd_shutdown(struct snd_pcm_substream *substream)
  387. {
  388. int ret;
  389. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  390. struct snd_soc_card *card = rtd->card;
  391. struct msm_common_pdata *pdata = msm_common_get_pdata(card);
  392. const char *stream_name = rtd->dai_link->stream_name;
  393. int index = get_intf_index(stream_name);
  394. struct clk_cfg intf_clk_cfg;
  395. memset(&intf_clk_cfg, 0, sizeof(struct clk_cfg));
  396. pr_debug("%s(): substream = %s stream = %d\n", __func__,
  397. substream->name, substream->stream);
  398. if (!pdata) {
  399. dev_err(card->dev, "%s: pdata is NULL\n", __func__);
  400. return;
  401. }
  402. check_userspace_service_state(rtd, pdata);
  403. if (index >= 0) {
  404. mutex_lock(&pdata->lock[index]);
  405. if (pdata->mi2s_gpio_p[index]) {
  406. atomic_dec(&pdata->mi2s_gpio_ref_cnt[index]);
  407. if (atomic_read(&pdata->mi2s_gpio_ref_cnt[index]) == 0) {
  408. if ((strnstr(stream_name, "TDM", strlen(stream_name)))) {
  409. intf_clk_cfg.clk_id = get_tdm_clk_id(index);
  410. ret = audio_prm_set_lpass_clk_cfg(&intf_clk_cfg, 0);
  411. if (ret < 0)
  412. pr_err("%s: prm clk cfg set failed ret %d\n",
  413. __func__, ret);
  414. } else if((strnstr(stream_name, "MI2S", strlen(stream_name)))) {
  415. intf_clk_cfg.clk_id = get_mi2s_clk_id(index);
  416. ret = audio_prm_set_lpass_clk_cfg(&intf_clk_cfg, 0);
  417. if (ret < 0)
  418. pr_err("%s: prm mi2s clk cfg disable failed ret %d\n",
  419. __func__, ret);
  420. } else {
  421. pr_err("%s: invalid stream name: %s\n",
  422. __func__, stream_name);
  423. }
  424. ret = msm_cdc_pinctrl_select_sleep_state(
  425. pdata->mi2s_gpio_p[index]);
  426. if (ret)
  427. dev_err(card->dev,
  428. "%s: pinctrl set actv fail %d\n",
  429. __func__, ret);
  430. }
  431. }
  432. mutex_unlock(&pdata->lock[index]);
  433. }
  434. }
  435. int msm_common_snd_init(struct platform_device *pdev, struct snd_soc_card *card)
  436. {
  437. struct msm_common_pdata *common_pdata = NULL;
  438. int count, ret = 0;
  439. common_pdata = kcalloc(1, sizeof(struct msm_common_pdata), GFP_KERNEL);
  440. if (!common_pdata)
  441. return -ENOMEM;
  442. for (count = 0; count < MI2S_TDM_AUXPCM_MAX; count++) {
  443. mutex_init(&common_pdata->lock[count]);
  444. atomic_set(&common_pdata->mi2s_gpio_ref_cnt[count], 0);
  445. }
  446. ret = of_property_read_u32(pdev->dev.of_node, "qcom,tdm-max-slots",
  447. &common_pdata->tdm_max_slots);
  448. if (ret) {
  449. dev_info(&pdev->dev, "%s: No DT match for tdm max slots\n",
  450. __func__);
  451. }
  452. if ((common_pdata->tdm_max_slots <= 0) || (common_pdata->tdm_max_slots >
  453. TDM_MAX_SLOTS)) {
  454. common_pdata->tdm_max_slots = TDM_MAX_SLOTS;
  455. dev_info(&pdev->dev, "%s: Using default tdm max slot: %d\n",
  456. __func__, common_pdata->tdm_max_slots);
  457. }
  458. common_pdata->mi2s_gpio_p[PRI_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  459. "qcom,pri-mi2s-gpios", 0);
  460. common_pdata->mi2s_gpio_p[SEC_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  461. "qcom,sec-mi2s-gpios", 0);
  462. common_pdata->mi2s_gpio_p[TER_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  463. "qcom,tert-mi2s-gpios", 0);
  464. common_pdata->mi2s_gpio_p[QUAT_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  465. "qcom,quat-mi2s-gpios", 0);
  466. common_pdata->mi2s_gpio_p[QUIN_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  467. "qcom,quin-mi2s-gpios", 0);
  468. common_pdata->mi2s_gpio_p[SEN_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  469. "qcom,sen-mi2s-gpios", 0);
  470. common_pdata->aud_dev_state = devm_kcalloc(&pdev->dev, card->num_links,
  471. sizeof(uint8_t), GFP_KERNEL);
  472. dev_info(&pdev->dev, "num_links %d \n", card->num_links);
  473. common_pdata->num_aud_devs = card->num_links;
  474. aud_dev_sysfs_init(common_pdata);
  475. msm_common_set_pdata(card, common_pdata);
  476. return 0;
  477. };
  478. void msm_common_snd_deinit(struct msm_common_pdata *common_pdata)
  479. {
  480. int count;
  481. if (!common_pdata)
  482. return;
  483. for (count = 0; count < MI2S_TDM_AUXPCM_MAX; count++) {
  484. mutex_destroy(&common_pdata->lock[count]);
  485. }
  486. }
  487. int msm_channel_map_info(struct snd_kcontrol *kcontrol,
  488. struct snd_ctl_elem_info *uinfo)
  489. {
  490. uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
  491. uinfo->count = sizeof(uint32_t) * MAX_PORT;
  492. return 0;
  493. }
  494. int msm_channel_map_get(struct snd_kcontrol *kcontrol,
  495. struct snd_ctl_elem_value *ucontrol)
  496. {
  497. struct chmap_pdata *kctl_pdata =
  498. (struct chmap_pdata *)kcontrol->private_data;
  499. struct snd_soc_dai *codec_dai = NULL;
  500. int backend_id = 0;
  501. uint32_t rx_ch[MAX_PORT] = {0}, tx_ch[MAX_PORT] = {0};
  502. uint32_t rx_ch_cnt = 0, tx_ch_cnt = 0;
  503. uint32_t *chmap_data = NULL;
  504. int ret = 0, len = 0, i = 0;
  505. if (kctl_pdata == NULL) {
  506. pr_debug("%s: chmap_pdata is not initialized\n", __func__);
  507. return -EINVAL;
  508. }
  509. codec_dai = kctl_pdata->dai[0];
  510. backend_id = kctl_pdata->id;
  511. switch (backend_id) {
  512. case SLIM: {
  513. uint32_t *chmap;
  514. uint32_t ch_cnt;
  515. ret = snd_soc_dai_get_channel_map(codec_dai,
  516. &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
  517. if (ret || (tx_ch_cnt == 0 && rx_ch_cnt == 0)) {
  518. pr_debug("%s: got incorrect channel map for backend_id:%d\n",
  519. __func__, backend_id);
  520. return ret;
  521. }
  522. if (rx_ch_cnt) {
  523. chmap = rx_ch;
  524. ch_cnt = rx_ch_cnt;
  525. } else {
  526. chmap = tx_ch;
  527. ch_cnt = tx_ch_cnt;
  528. }
  529. len = sizeof(uint32_t) * (ch_cnt + 1);
  530. chmap_data = kzalloc(len, GFP_KERNEL);
  531. if (!chmap_data)
  532. return -ENOMEM;
  533. chmap_data[0] = ch_cnt;
  534. for (i = 0; i < ch_cnt; i++)
  535. chmap_data[i+1] = chmap[i];
  536. memcpy(ucontrol->value.bytes.data, chmap_data, len);
  537. break;
  538. }
  539. case CODEC_DMA: {
  540. uint32_t cur_rx_ch = 0, cur_tx_ch = 0;
  541. uint32_t cur_rx_ch_cnt = 0, cur_tx_ch_cnt = 0;
  542. for (i = 0; i < kctl_pdata->num_codec_dai; ++i) {
  543. codec_dai = kctl_pdata->dai[i];
  544. if(!codec_dai) {
  545. continue;
  546. }
  547. cur_rx_ch_cnt = 0;
  548. cur_tx_ch_cnt = 0;
  549. cur_tx_ch = 0;
  550. cur_rx_ch = 0;
  551. ret = snd_soc_dai_get_channel_map(codec_dai,
  552. &cur_tx_ch_cnt, &cur_tx_ch,
  553. &cur_rx_ch_cnt, &cur_rx_ch);
  554. /* DAIs that not supports get_channel_map should pass */
  555. if (ret && (ret != -ENOTSUPP)) {
  556. pr_err("%s: get channel map failed for backend_id:%d,"
  557. " ret:%d\n",
  558. __func__, backend_id, ret);
  559. return ret;
  560. }
  561. rx_ch_cnt += cur_rx_ch_cnt;
  562. tx_ch_cnt += cur_tx_ch_cnt;
  563. rx_ch[0] |= cur_rx_ch;
  564. tx_ch[0] |= cur_tx_ch;
  565. }
  566. /* reset return value from the loop above */
  567. ret = 0;
  568. if (rx_ch_cnt == 0 && tx_ch_cnt == 0) {
  569. pr_debug("%s: got incorrect channel map for backend_id:%d, ",
  570. "RX Channel Count:%d,"
  571. "TX Channel Count:%d\n",
  572. __func__, backend_id, rx_ch_cnt, tx_ch_cnt);
  573. return ret;
  574. }
  575. chmap_data = kzalloc(sizeof(uint32_t) * 2, GFP_KERNEL);
  576. if (!chmap_data)
  577. return -ENOMEM;
  578. if (rx_ch_cnt) {
  579. chmap_data[0] = rx_ch_cnt;
  580. chmap_data[1] = rx_ch[0];
  581. } else {
  582. chmap_data[0] = tx_ch_cnt;
  583. chmap_data[1] = tx_ch[0];
  584. }
  585. memcpy(ucontrol->value.bytes.data, chmap_data,
  586. sizeof(uint32_t) * 2);
  587. break;
  588. }
  589. default:
  590. pr_err("%s, Invalid backend %d\n", __func__, backend_id);
  591. ret = -EINVAL;
  592. break;
  593. }
  594. kfree(chmap_data);
  595. return ret;
  596. }
  597. void msm_common_get_backend_name(const char *stream_name, char **backend_name)
  598. {
  599. char arg[ARRAY_SZ] = {0};
  600. char value[61] = {0};
  601. sscanf(stream_name, "%20[^-]-%60s", arg, value);
  602. *backend_name = kzalloc(ARRAY_SZ, GFP_KERNEL);
  603. if (!(*backend_name))
  604. return;
  605. strlcpy(*backend_name, arg, ARRAY_SZ);
  606. }
  607. int msm_common_dai_link_init(struct snd_soc_pcm_runtime *rtd)
  608. {
  609. struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
  610. struct snd_soc_component *component = NULL;
  611. struct snd_soc_dai_link *dai_link = rtd->dai_link;
  612. struct device *dev = rtd->card->dev;
  613. int ret = 0;
  614. int index = 0;
  615. const char *mixer_ctl_name = CODEC_CHMAP;
  616. char *mixer_str = NULL;
  617. char *backend_name = NULL;
  618. uint32_t ctl_len = 0;
  619. struct chmap_pdata *pdata;
  620. struct snd_kcontrol *kctl;
  621. struct snd_kcontrol_new msm_common_channel_map[1] = {
  622. {
  623. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  624. .name = "?",
  625. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
  626. .info = msm_channel_map_info,
  627. .get = msm_channel_map_get,
  628. .private_value = 0,
  629. }
  630. };
  631. if (!codec_dai) {
  632. pr_err("%s: failed to get codec dai", __func__);
  633. return -EINVAL;
  634. }
  635. component = codec_dai->component;
  636. msm_common_get_backend_name(dai_link->stream_name, &backend_name);
  637. if (!backend_name) {
  638. pr_err("%s: failed to get backend name", __func__);
  639. return -EINVAL;
  640. }
  641. pdata = devm_kzalloc(dev, sizeof(struct chmap_pdata), GFP_KERNEL);
  642. if (!pdata)
  643. return -ENOMEM;
  644. if ((!strncmp(backend_name, "SLIM", strlen("SLIM"))) ||
  645. (!strncmp(backend_name, "CODEC_DMA", strlen("CODEC_DMA")))) {
  646. ctl_len = strlen(dai_link->stream_name) + 1 +
  647. strlen(mixer_ctl_name) + 1;
  648. mixer_str = kzalloc(ctl_len, GFP_KERNEL);
  649. if (!mixer_str)
  650. return -ENOMEM;
  651. snprintf(mixer_str, ctl_len, "%s %s", dai_link->stream_name,
  652. mixer_ctl_name);
  653. msm_common_channel_map[0].name = mixer_str;
  654. msm_common_channel_map[0].private_value = 0;
  655. pr_debug("Registering new mixer ctl %s\n", mixer_str);
  656. ret = snd_soc_add_component_controls(component,
  657. msm_common_channel_map,
  658. ARRAY_SIZE(msm_common_channel_map));
  659. kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str);
  660. if (!kctl) {
  661. pr_err("failed to get kctl %s\n", mixer_str);
  662. ret = -EINVAL;
  663. goto free_mixer_str;
  664. }
  665. pdata->dai[0] = codec_dai;
  666. pdata->num_codec_dai = 1;
  667. if (!strncmp(backend_name, "SLIM", strlen("SLIM"))) {
  668. pdata->id = SLIM;
  669. } else {
  670. pdata->id = CODEC_DMA;
  671. if (rtd->num_codecs <= MAX_CODEC_DAI) {
  672. pdata->num_codec_dai = rtd->num_codecs;
  673. for_each_rtd_codec_dais(rtd, index, codec_dai) {
  674. pdata->dai[index] = codec_dai;
  675. }
  676. }
  677. }
  678. kctl->private_data = pdata;
  679. free_mixer_str:
  680. kfree(backend_name);
  681. kfree(mixer_str);
  682. }
  683. return ret;
  684. }