msm_common.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  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 <asoc/msm-cdc-pinctrl.h>
  21. #include <dsp/spf-core.h>
  22. #include <dsp/msm_audio_ion.h>
  23. #include <sound/info.h>
  24. #include "msm_common.h"
  25. struct snd_card_pdata {
  26. struct kobject snd_card_kobj;
  27. int card_status;
  28. }*snd_card_pdata;
  29. #define to_asoc_mach_common_pdata(kobj) \
  30. container_of((kobj), struct msm_common_pdata, aud_dev_kobj)
  31. #define DEVICE_ENABLE 1
  32. #define DEVICE_DISABLE 0
  33. #define ARRAY_SZ 21
  34. #define BUF_SZ 32
  35. #define DIR_SZ 10
  36. static struct attribute device_state_attr = {
  37. .name = "state",
  38. .mode = 0660,
  39. };
  40. static struct attribute card_state_attr = {
  41. .name = "card_state",
  42. .mode = 0660,
  43. };
  44. #define MAX_PORT 20
  45. #define CODEC_CHMAP "Channel Map"
  46. enum backend_id {
  47. SLIM = 1,
  48. CODEC_DMA,
  49. };
  50. struct chmap_pdata {
  51. int id;
  52. struct snd_soc_dai *dai;
  53. };
  54. #define MAX_USR_INPUT 10
  55. static ssize_t aud_dev_sysfs_store(struct kobject *kobj,
  56. struct attribute *attr,
  57. const char *buf, size_t count)
  58. {
  59. ssize_t ret = -EINVAL;
  60. struct msm_common_pdata *pdata = to_asoc_mach_common_pdata(kobj);
  61. uint32_t pcm_id, state = 0;
  62. if (count > MAX_USR_INPUT) {
  63. pr_err("%s: invalid string written", __func__);
  64. goto done;
  65. }
  66. sscanf(buf, "%d %d", &pcm_id, &state);
  67. if ((pcm_id > pdata->num_aud_devs) || (pcm_id < 0)) {
  68. pr_err("%s: invalid pcm id %d \n", __func__, pcm_id);
  69. goto done;
  70. }
  71. if ((state > DEVICE_ENABLE) || (state < DEVICE_DISABLE)) {
  72. pr_err("%s: invalid state %d \n", __func__, state);
  73. goto done;
  74. }
  75. pr_debug("%s: pcm_id %d state %d \n", __func__, pcm_id, state);
  76. pdata->aud_dev_state[pcm_id] = state;
  77. if ( state == DEVICE_ENABLE && (pdata->dsp_sessions_closed != 0))
  78. pdata->dsp_sessions_closed = 0;
  79. ret = count;
  80. done:
  81. return ret;
  82. }
  83. static const struct sysfs_ops aud_dev_sysfs_ops = {
  84. .store = aud_dev_sysfs_store,
  85. };
  86. static struct kobj_type aud_dev_ktype = {
  87. .sysfs_ops = &aud_dev_sysfs_ops,
  88. };
  89. static int aud_dev_sysfs_init(struct msm_common_pdata *pdata)
  90. {
  91. int ret = 0;
  92. char dir[10] = "aud_dev";
  93. ret = kobject_init_and_add(&pdata->aud_dev_kobj, &aud_dev_ktype,
  94. kernel_kobj, dir);
  95. if (ret < 0) {
  96. pr_err("%s: Failed to add kobject %s, err = %d\n",
  97. __func__, dir, ret);
  98. goto done;
  99. }
  100. ret = sysfs_create_file(&pdata->aud_dev_kobj, &device_state_attr);
  101. if (ret < 0) {
  102. pr_err("%s: Failed to add wdsp_boot sysfs entry to %s\n",
  103. __func__, dir);
  104. goto fail_create_file;
  105. }
  106. return ret;
  107. fail_create_file:
  108. kobject_put(&pdata->aud_dev_kobj);
  109. done:
  110. return ret;
  111. }
  112. int snd_card_notify_user(int card_status)
  113. {
  114. snd_card_pdata->card_status = card_status;
  115. sysfs_notify(&snd_card_pdata->snd_card_kobj, NULL, "card_state");
  116. return 0;
  117. }
  118. static ssize_t snd_card_sysfs_show(struct kobject *kobj,
  119. struct attribute *attr, char *buf)
  120. {
  121. return snprintf(buf, BUF_SZ, "%d", snd_card_pdata->card_status);
  122. }
  123. static ssize_t snd_card_sysfs_store(struct kobject *kobj,
  124. struct attribute *attr, const char *buf, size_t count)
  125. {
  126. sscanf(buf, "%d", &snd_card_pdata->card_status);
  127. sysfs_notify(&snd_card_pdata->snd_card_kobj, NULL, "card_state");
  128. return 0;
  129. }
  130. static const struct sysfs_ops snd_card_sysfs_ops = {
  131. .show = snd_card_sysfs_show,
  132. .store = snd_card_sysfs_store,
  133. };
  134. static struct kobj_type snd_card_ktype = {
  135. .sysfs_ops = &snd_card_sysfs_ops,
  136. };
  137. int snd_card_sysfs_init(void)
  138. {
  139. int ret = 0;
  140. char dir[DIR_SZ] = "snd_card";
  141. snd_card_pdata = kcalloc(1, sizeof(struct snd_card_pdata), GFP_KERNEL);
  142. ret = kobject_init_and_add(&snd_card_pdata->snd_card_kobj, &snd_card_ktype,
  143. kernel_kobj, dir);
  144. if (ret < 0) {
  145. pr_err("%s: Failed to add kobject %s, err = %d\n",
  146. __func__, dir, ret);
  147. goto done;
  148. }
  149. ret = sysfs_create_file(&snd_card_pdata->snd_card_kobj, &card_state_attr);
  150. if (ret < 0) {
  151. pr_err("%s: Failed to add snd_card sysfs entry to %s\n",
  152. __func__, dir);
  153. goto fail_create_file;
  154. }
  155. return ret;
  156. fail_create_file:
  157. kobject_put(&snd_card_pdata->snd_card_kobj);
  158. done:
  159. return ret;
  160. }
  161. static void check_userspace_service_state(struct snd_soc_pcm_runtime *rtd,
  162. struct msm_common_pdata *pdata)
  163. {
  164. dev_info(rtd->card->dev,"%s: pcm_id %d state %d\n", __func__,
  165. rtd->num, pdata->aud_dev_state[rtd->num]);
  166. if (pdata->aud_dev_state[rtd->num] == DEVICE_ENABLE) {
  167. dev_info(rtd->card->dev, "%s userspace service crashed\n",
  168. __func__);
  169. if (pdata->dsp_sessions_closed == 0) {
  170. /*Issue close all graph cmd to DSP*/
  171. spf_core_apm_close_all();
  172. /*unmap all dma mapped buffers*/
  173. msm_audio_ion_crash_handler();
  174. pdata->dsp_sessions_closed = 1;
  175. }
  176. /*Reset the state as sysfs node wont be triggred*/
  177. pdata->aud_dev_state[rtd->num] = 0;
  178. }
  179. }
  180. static int get_intf_index(const char *stream_name)
  181. {
  182. if (strnstr(stream_name, "PRIMARY", strlen(stream_name)))
  183. return PRI_MI2S_TDM_AUXPCM;
  184. else if (strnstr(stream_name, "SECONDARY", strlen(stream_name)))
  185. return SEC_MI2S_TDM_AUXPCM;
  186. else if (strnstr(stream_name, "TERTIARY", strlen(stream_name)))
  187. return TER_MI2S_TDM_AUXPCM;
  188. else if (strnstr(stream_name, "QUATERNARY", strlen(stream_name)))
  189. return QUAT_MI2S_TDM_AUXPCM;
  190. else if (strnstr(stream_name, "QUINARY", strlen(stream_name)))
  191. return QUIN_MI2S_TDM_AUXPCM;
  192. else if (strnstr(stream_name, "SENARY", strlen(stream_name)))
  193. return SEN_MI2S_TDM_AUXPCM;
  194. else {
  195. pr_debug("%s: stream name %s does not match\n", __func__, stream_name);
  196. return -EINVAL;
  197. }
  198. }
  199. int msm_common_snd_startup(struct snd_pcm_substream *substream)
  200. {
  201. int ret = 0;
  202. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  203. struct snd_soc_card *card = rtd->card;
  204. struct msm_common_pdata *pdata = msm_common_get_pdata(card);
  205. const char *stream_name = rtd->dai_link->stream_name;
  206. int index = get_intf_index(stream_name);
  207. dev_dbg(rtd->card->dev,
  208. "%s: substream = %s stream = %d\n",
  209. __func__, substream->name, substream->stream);
  210. if (!pdata) {
  211. dev_err(rtd->card->dev, "%s: pdata is NULL\n", __func__);
  212. return -EINVAL;
  213. }
  214. if (index >= 0) {
  215. mutex_lock(&pdata->lock[index]);
  216. if (pdata->mi2s_gpio_p[index]) {
  217. if (atomic_read(&(pdata->mi2s_gpio_ref_cnt[index])) == 0) {
  218. ret = msm_cdc_pinctrl_select_active_state(
  219. pdata->mi2s_gpio_p[index]);
  220. if (ret) {
  221. pr_err("%s:pinctrl set actve fail with %d\n",
  222. __func__, ret);
  223. goto done;
  224. }
  225. }
  226. atomic_inc(&(pdata->mi2s_gpio_ref_cnt[index]));
  227. }
  228. done:
  229. mutex_unlock(&pdata->lock[index]);
  230. }
  231. return ret;
  232. }
  233. void msm_common_snd_shutdown(struct snd_pcm_substream *substream)
  234. {
  235. int ret;
  236. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  237. struct snd_soc_card *card = rtd->card;
  238. struct msm_common_pdata *pdata = msm_common_get_pdata(card);
  239. const char *stream_name = rtd->dai_link->stream_name;
  240. int index = get_intf_index(stream_name);
  241. pr_debug("%s(): substream = %s stream = %d\n", __func__,
  242. substream->name, substream->stream);
  243. if (!pdata) {
  244. dev_err(card->dev, "%s: pdata is NULL\n", __func__);
  245. return;
  246. }
  247. check_userspace_service_state(rtd, pdata);
  248. if (index >= 0) {
  249. mutex_lock(&pdata->lock[index]);
  250. if (pdata->mi2s_gpio_p[index]) {
  251. atomic_dec(&pdata->mi2s_gpio_ref_cnt[index]);
  252. if (atomic_read(&pdata->mi2s_gpio_ref_cnt[index]) == 0) {
  253. ret = msm_cdc_pinctrl_select_active_state(
  254. pdata->mi2s_gpio_p[index]);
  255. if (ret)
  256. dev_err(card->dev,
  257. "%s: pinctrl set actv fail %d\n",
  258. __func__, ret);
  259. }
  260. }
  261. mutex_unlock(&pdata->lock[index]);
  262. }
  263. }
  264. int msm_common_snd_init(struct platform_device *pdev, struct snd_soc_card *card)
  265. {
  266. struct msm_common_pdata *common_pdata = NULL;
  267. int count;
  268. common_pdata = kcalloc(1, sizeof(struct msm_common_pdata), GFP_KERNEL);
  269. if (!common_pdata)
  270. return -ENOMEM;
  271. for (count = 0; count < MI2S_TDM_AUXPCM_MAX; count++) {
  272. mutex_init(&common_pdata->lock[count]);
  273. atomic_set(&common_pdata->mi2s_gpio_ref_cnt[count], 0);
  274. }
  275. common_pdata->mi2s_gpio_p[PRI_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  276. "qcom,pri-mi2s-gpios", 0);
  277. common_pdata->mi2s_gpio_p[SEC_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  278. "qcom,sec-mi2s-gpios", 0);
  279. common_pdata->mi2s_gpio_p[TER_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  280. "qcom,tert-mi2s-gpios", 0);
  281. common_pdata->mi2s_gpio_p[QUAT_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  282. "qcom,quat-mi2s-gpios", 0);
  283. common_pdata->mi2s_gpio_p[QUIN_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  284. "qcom,quin-mi2s-gpios", 0);
  285. common_pdata->mi2s_gpio_p[SEN_MI2S_TDM_AUXPCM] = of_parse_phandle(pdev->dev.of_node,
  286. "qcom,sen-mi2s-gpios", 0);
  287. common_pdata->aud_dev_state = devm_kcalloc(&pdev->dev, card->num_links,
  288. sizeof(uint8_t), GFP_KERNEL);
  289. dev_info(&pdev->dev, "num_links %d \n", card->num_links);
  290. common_pdata->num_aud_devs = card->num_links;
  291. aud_dev_sysfs_init(common_pdata);
  292. msm_common_set_pdata(card, common_pdata);
  293. return 0;
  294. };
  295. void msm_common_snd_deinit(struct msm_common_pdata *common_pdata)
  296. {
  297. int count;
  298. if (!common_pdata)
  299. return;
  300. for (count = 0; count < MI2S_TDM_AUXPCM_MAX; count++) {
  301. mutex_destroy(&common_pdata->lock[count]);
  302. }
  303. }
  304. int msm_channel_map_info(struct snd_kcontrol *kcontrol,
  305. struct snd_ctl_elem_info *uinfo)
  306. {
  307. uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
  308. uinfo->count = sizeof(uint32_t) * MAX_PORT;
  309. return 0;
  310. }
  311. int msm_channel_map_get(struct snd_kcontrol *kcontrol,
  312. struct snd_ctl_elem_value *ucontrol)
  313. {
  314. struct chmap_pdata *kctl_pdata =
  315. (struct chmap_pdata *)kcontrol->private_data;
  316. struct snd_soc_dai *codec_dai = NULL;
  317. int backend_id = 0;
  318. uint32_t rx_ch[MAX_PORT], tx_ch[MAX_PORT];
  319. uint32_t rx_ch_cnt = 0, tx_ch_cnt = 0;
  320. uint32_t *chmap_data = NULL;
  321. int ret = 0, len = 0;
  322. if (kctl_pdata == NULL) {
  323. pr_debug("%s: chmap_pdata is not initialized\n", __func__);
  324. return -EINVAL;
  325. }
  326. codec_dai = kctl_pdata->dai;
  327. backend_id = kctl_pdata->id;
  328. ret = snd_soc_dai_get_channel_map(codec_dai,
  329. &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
  330. if (ret || (tx_ch_cnt == 0 && rx_ch_cnt == 0)) {
  331. pr_err("%s: get channel map failed for %d\n",
  332. __func__, backend_id);
  333. return ret;
  334. }
  335. switch (backend_id) {
  336. case SLIM: {
  337. uint32_t *chmap;
  338. uint32_t ch_cnt, i;
  339. if (rx_ch_cnt) {
  340. chmap = rx_ch;
  341. ch_cnt = rx_ch_cnt;
  342. } else {
  343. chmap = tx_ch;
  344. ch_cnt = tx_ch_cnt;
  345. }
  346. len = sizeof(uint32_t) * (ch_cnt + 1);
  347. chmap_data = kzalloc(len, GFP_KERNEL);
  348. if (!chmap_data)
  349. return -ENOMEM;
  350. chmap_data[0] = ch_cnt;
  351. for (i = 0; i < ch_cnt; i++)
  352. chmap_data[i+1] = chmap[i];
  353. memcpy(ucontrol->value.bytes.data, chmap_data, len);
  354. break;
  355. }
  356. case CODEC_DMA: {
  357. chmap_data = kzalloc(sizeof(uint32_t) * 2, GFP_KERNEL);
  358. if (!chmap_data)
  359. return -ENOMEM;
  360. if (rx_ch_cnt) {
  361. chmap_data[0] = rx_ch_cnt;
  362. chmap_data[1] = rx_ch[0];
  363. } else {
  364. chmap_data[0] = tx_ch_cnt;
  365. chmap_data[1] = tx_ch[0];
  366. }
  367. memcpy(ucontrol->value.bytes.data, chmap_data,
  368. sizeof(uint32_t) * 2);
  369. break;
  370. }
  371. default:
  372. pr_err("%s, Invalid backend %d\n", __func__, backend_id);
  373. ret = -EINVAL;
  374. break;
  375. }
  376. kfree(chmap_data);
  377. return ret;
  378. }
  379. void msm_common_get_backend_name(const char *stream_name, char **backend_name)
  380. {
  381. char arg[ARRAY_SZ] = {0};
  382. char value[61] = {0};
  383. sscanf(stream_name, "%20[^-]-%60s", arg, value);
  384. *backend_name = kzalloc(ARRAY_SZ, GFP_KERNEL);
  385. if (!(*backend_name))
  386. return;
  387. strlcpy(*backend_name, arg, ARRAY_SZ);
  388. }
  389. int msm_common_dai_link_init(struct snd_soc_pcm_runtime *rtd)
  390. {
  391. struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
  392. struct snd_soc_component *component = NULL;
  393. struct snd_soc_dai_link *dai_link = rtd->dai_link;
  394. struct device *dev = rtd->card->dev;
  395. int ret = 0;
  396. const char *mixer_ctl_name = CODEC_CHMAP;
  397. char *mixer_str = NULL;
  398. char *backend_name = NULL;
  399. uint32_t ctl_len = 0;
  400. struct chmap_pdata *pdata;
  401. struct snd_kcontrol *kctl;
  402. struct snd_kcontrol_new msm_common_channel_map[1] = {
  403. {
  404. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  405. .name = "?",
  406. .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
  407. .info = msm_channel_map_info,
  408. .get = msm_channel_map_get,
  409. .private_value = 0,
  410. }
  411. };
  412. if (!codec_dai) {
  413. pr_err("%s: failed to get codec dai", __func__);
  414. return -EINVAL;
  415. }
  416. component = codec_dai->component;
  417. msm_common_get_backend_name(dai_link->stream_name, &backend_name);
  418. if (!backend_name) {
  419. pr_err("%s: failed to get backend name", __func__);
  420. return -EINVAL;
  421. }
  422. pdata = devm_kzalloc(dev, sizeof(struct chmap_pdata), GFP_KERNEL);
  423. if (!pdata)
  424. return -ENOMEM;
  425. if ((!strncmp(backend_name, "SLIM", strlen("SLIM"))) ||
  426. (!strncmp(backend_name, "CODEC_DMA", strlen("CODEC_DMA")))) {
  427. ctl_len = strlen(dai_link->stream_name) + 1 +
  428. strlen(mixer_ctl_name) + 1;
  429. mixer_str = kzalloc(ctl_len, GFP_KERNEL);
  430. if (!mixer_str)
  431. return -ENOMEM;
  432. snprintf(mixer_str, ctl_len, "%s %s", dai_link->stream_name,
  433. mixer_ctl_name);
  434. msm_common_channel_map[0].name = mixer_str;
  435. msm_common_channel_map[0].private_value = 0;
  436. pr_debug("Registering new mixer ctl %s\n", mixer_str);
  437. ret = snd_soc_add_component_controls(component,
  438. msm_common_channel_map,
  439. ARRAY_SIZE(msm_common_channel_map));
  440. kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str);
  441. if (!kctl) {
  442. pr_err("failed to get kctl %s\n", mixer_str);
  443. ret = -EINVAL;
  444. goto free_mixer_str;
  445. }
  446. if (!strncmp(backend_name, "SLIM", strlen("SLIM")))
  447. pdata->id = SLIM;
  448. else
  449. pdata->id = CODEC_DMA;
  450. pdata->dai = codec_dai;
  451. kctl->private_data = pdata;
  452. free_mixer_str:
  453. kfree(backend_name);
  454. kfree(mixer_str);
  455. }
  456. return ret;
  457. }