msm-pcm-dtmf-v2.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved.
  3. */
  4. #include <linux/init.h>
  5. #include <linux/module.h>
  6. #include <linux/time.h>
  7. #include <linux/wait.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/slab.h>
  10. #include <linux/dma-mapping.h>
  11. #include <sound/core.h>
  12. #include <sound/soc.h>
  13. #include <sound/pcm.h>
  14. #include <dsp/q6afe-v2.h>
  15. #include <dsp/q6voice.h>
  16. #include "msm-pcm-q6-v2.h"
  17. #include "msm-pcm-routing-v2.h"
  18. #define DRV_NAME "msm-pcm-dtmf-v2"
  19. enum {
  20. DTMF_IN_RX,
  21. DTMF_IN_TX,
  22. };
  23. enum format {
  24. FORMAT_S16_LE = 2
  25. };
  26. struct dtmf_det_info {
  27. char session[MAX_SESSION_NAME_LEN];
  28. uint8_t dir;
  29. uint16_t high_freq;
  30. uint16_t low_freq;
  31. };
  32. struct dtmf_buf_node {
  33. struct list_head list;
  34. struct dtmf_det_info dtmf_det_pkt;
  35. };
  36. enum dtmf_state {
  37. DTMF_GEN_RX_STOPPED,
  38. DTMF_GEN_RX_STARTED,
  39. };
  40. #define DTMF_MAX_Q_LEN 10
  41. #define DTMF_PKT_SIZE sizeof(struct dtmf_det_info)
  42. struct dtmf_drv_info {
  43. enum dtmf_state state;
  44. struct snd_pcm_substream *capture_substream;
  45. struct list_head out_queue;
  46. struct list_head free_out_queue;
  47. wait_queue_head_t out_wait;
  48. struct mutex lock;
  49. spinlock_t dsp_lock;
  50. uint8_t capture_start;
  51. uint8_t capture_instance;
  52. unsigned int pcm_capture_size;
  53. unsigned int pcm_capture_count;
  54. unsigned int pcm_capture_irq_pos;
  55. unsigned int pcm_capture_buf_pos;
  56. };
  57. static struct snd_pcm_hardware msm_pcm_hardware = {
  58. .info = (SNDRV_PCM_INFO_MMAP |
  59. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  60. SNDRV_PCM_INFO_MMAP_VALID |
  61. SNDRV_PCM_INFO_INTERLEAVED),
  62. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  63. .channels_min = 1,
  64. .channels_max = 1,
  65. .buffer_bytes_max = (sizeof(struct dtmf_buf_node) * DTMF_MAX_Q_LEN),
  66. .period_bytes_min = DTMF_PKT_SIZE,
  67. .period_bytes_max = DTMF_PKT_SIZE,
  68. .periods_min = DTMF_MAX_Q_LEN,
  69. .periods_max = DTMF_MAX_Q_LEN,
  70. .fifo_size = 0,
  71. };
  72. static int msm_dtmf_rx_generate_put(struct snd_kcontrol *kcontrol,
  73. struct snd_ctl_elem_value *ucontrol)
  74. {
  75. uint16_t low_freq = ucontrol->value.integer.value[0];
  76. uint16_t high_freq = ucontrol->value.integer.value[1];
  77. int64_t duration = ucontrol->value.integer.value[2];
  78. uint16_t gain = ucontrol->value.integer.value[3];
  79. pr_debug("%s: low_freq=%d high_freq=%d duration=%d gain=%d\n",
  80. __func__, low_freq, high_freq, (int)duration, gain);
  81. afe_dtmf_generate_rx(duration, high_freq, low_freq, gain);
  82. return 0;
  83. }
  84. static int msm_dtmf_rx_generate_get(struct snd_kcontrol *kcontrol,
  85. struct snd_ctl_elem_value *ucontrol)
  86. {
  87. pr_debug("%s:\n", __func__);
  88. ucontrol->value.integer.value[0] = 0;
  89. return 0;
  90. }
  91. static int msm_dtmf_detect_voice_rx_put(struct snd_kcontrol *kcontrol,
  92. struct snd_ctl_elem_value *ucontrol)
  93. {
  94. int enable = ucontrol->value.integer.value[0];
  95. pr_debug("%s: enable=%d\n", __func__, enable);
  96. voc_enable_dtmf_rx_detection(voc_get_session_id(VOICE_SESSION_NAME),
  97. enable);
  98. return 0;
  99. }
  100. static int msm_dtmf_detect_voice_rx_get(struct snd_kcontrol *kcontrol,
  101. struct snd_ctl_elem_value *ucontrol)
  102. {
  103. ucontrol->value.integer.value[0] = 0;
  104. return 0;
  105. }
  106. static int msm_dtmf_detect_volte_rx_put(struct snd_kcontrol *kcontrol,
  107. struct snd_ctl_elem_value *ucontrol)
  108. {
  109. int enable = ucontrol->value.integer.value[0];
  110. pr_debug("%s: enable=%d\n", __func__, enable);
  111. voc_enable_dtmf_rx_detection(voc_get_session_id(VOLTE_SESSION_NAME),
  112. enable);
  113. return 0;
  114. }
  115. static int msm_dtmf_detect_volte_rx_get(struct snd_kcontrol *kcontrol,
  116. struct snd_ctl_elem_value *ucontrol)
  117. {
  118. ucontrol->value.integer.value[0] = 0;
  119. return 0;
  120. }
  121. static struct snd_kcontrol_new msm_dtmf_controls[] = {
  122. SOC_SINGLE_MULTI_EXT("DTMF_Generate Rx Low High Duration Gain",
  123. SND_SOC_NOPM, 0, 5000, 0, 4,
  124. msm_dtmf_rx_generate_get,
  125. msm_dtmf_rx_generate_put),
  126. SOC_SINGLE_EXT("DTMF_Detect Rx Voice enable", SND_SOC_NOPM, 0, 1, 0,
  127. msm_dtmf_detect_voice_rx_get,
  128. msm_dtmf_detect_voice_rx_put),
  129. SOC_SINGLE_EXT("DTMF_Detect Rx VoLTE enable", SND_SOC_NOPM, 0, 1, 0,
  130. msm_dtmf_detect_volte_rx_get,
  131. msm_dtmf_detect_volte_rx_put),
  132. };
  133. static int msm_pcm_dtmf_probe(struct snd_soc_component *component)
  134. {
  135. snd_soc_add_component_controls(component, msm_dtmf_controls,
  136. ARRAY_SIZE(msm_dtmf_controls));
  137. return 0;
  138. }
  139. static void dtmf_rx_detected_cb(uint8_t *pkt,
  140. char *session,
  141. void *private_data)
  142. {
  143. struct dtmf_buf_node *buf_node = NULL;
  144. struct vss_istream_evt_rx_dtmf_detected *dtmf_det_pkt =
  145. (struct vss_istream_evt_rx_dtmf_detected *)pkt;
  146. struct dtmf_drv_info *prtd = private_data;
  147. unsigned long dsp_flags;
  148. pr_debug("%s\n", __func__);
  149. if (prtd->capture_substream == NULL)
  150. return;
  151. /* Copy dtmf detected info into out_queue. */
  152. spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
  153. /* discarding dtmf detection info till start is received */
  154. if (!list_empty(&prtd->free_out_queue) && prtd->capture_start) {
  155. buf_node = list_first_entry(&prtd->free_out_queue,
  156. struct dtmf_buf_node, list);
  157. list_del(&buf_node->list);
  158. buf_node->dtmf_det_pkt.high_freq = dtmf_det_pkt->high_freq;
  159. buf_node->dtmf_det_pkt.low_freq = dtmf_det_pkt->low_freq;
  160. if (session != NULL)
  161. strlcpy(buf_node->dtmf_det_pkt.session,
  162. session, MAX_SESSION_NAME_LEN);
  163. buf_node->dtmf_det_pkt.dir = DTMF_IN_RX;
  164. pr_debug("high =%d, low=%d session=%s\n",
  165. buf_node->dtmf_det_pkt.high_freq,
  166. buf_node->dtmf_det_pkt.low_freq,
  167. buf_node->dtmf_det_pkt.session);
  168. list_add_tail(&buf_node->list, &prtd->out_queue);
  169. prtd->pcm_capture_irq_pos += prtd->pcm_capture_count;
  170. spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
  171. snd_pcm_period_elapsed(prtd->capture_substream);
  172. } else {
  173. spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
  174. pr_err("DTMF detection pkt in Rx dropped, no free node available\n");
  175. }
  176. wake_up(&prtd->out_wait);
  177. }
  178. static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
  179. int channel, unsigned long hwoff,
  180. void __user *buf, unsigned long fbytes)
  181. {
  182. int ret = 0;
  183. struct dtmf_buf_node *buf_node = NULL;
  184. struct snd_pcm_runtime *runtime = substream->runtime;
  185. struct dtmf_drv_info *prtd = runtime->private_data;
  186. unsigned long dsp_flags;
  187. ret = wait_event_interruptible_timeout(prtd->out_wait,
  188. (!list_empty(&prtd->out_queue)),
  189. 1 * HZ);
  190. if (ret > 0) {
  191. if (fbytes <= DTMF_PKT_SIZE) {
  192. spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
  193. buf_node = list_first_entry(&prtd->out_queue,
  194. struct dtmf_buf_node, list);
  195. list_del(&buf_node->list);
  196. spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
  197. ret = copy_to_user(buf,
  198. &buf_node->dtmf_det_pkt,
  199. fbytes);
  200. if (ret) {
  201. pr_err("%s: Copy to user returned %d\n",
  202. __func__, ret);
  203. ret = -EFAULT;
  204. }
  205. spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
  206. list_add_tail(&buf_node->list,
  207. &prtd->free_out_queue);
  208. spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
  209. } else {
  210. pr_err("%s: Read count %lu > DTMF_PKT_SIZE\n",
  211. __func__, fbytes);
  212. ret = -ENOMEM;
  213. }
  214. } else if (ret == 0) {
  215. pr_err("%s: No UL data available\n", __func__);
  216. ret = -ETIMEDOUT;
  217. } else {
  218. pr_err("%s: Read was interrupted\n", __func__);
  219. ret = -ERESTARTSYS;
  220. }
  221. return ret;
  222. }
  223. static int msm_pcm_copy(struct snd_pcm_substream *substream, int a,
  224. unsigned long hwoff, void __user *buf, unsigned long fbytes)
  225. {
  226. int ret = 0;
  227. pr_debug("%s() DTMF\n", __func__);
  228. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  229. ret = msm_pcm_capture_copy(substream, a, hwoff, buf, fbytes);
  230. return ret;
  231. }
  232. static int msm_pcm_open(struct snd_pcm_substream *substream)
  233. {
  234. struct snd_pcm_runtime *runtime = substream->runtime;
  235. struct dtmf_drv_info *prtd = NULL;
  236. int ret = 0;
  237. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
  238. prtd = kzalloc(sizeof(struct dtmf_drv_info), GFP_KERNEL);
  239. if (prtd == NULL) {
  240. ret = -ENOMEM;
  241. goto done;
  242. }
  243. mutex_init(&prtd->lock);
  244. spin_lock_init(&prtd->dsp_lock);
  245. init_waitqueue_head(&prtd->out_wait);
  246. INIT_LIST_HEAD(&prtd->out_queue);
  247. INIT_LIST_HEAD(&prtd->free_out_queue);
  248. runtime->hw = msm_pcm_hardware;
  249. ret = snd_pcm_hw_constraint_integer(runtime,
  250. SNDRV_PCM_HW_PARAM_PERIODS);
  251. if (ret < 0)
  252. pr_info("snd_pcm_hw_constraint_integer failed\n");
  253. prtd->capture_substream = substream;
  254. prtd->capture_instance++;
  255. runtime->private_data = prtd;
  256. }
  257. done:
  258. return ret;
  259. }
  260. static int msm_pcm_close(struct snd_pcm_substream *substream)
  261. {
  262. int ret = 0;
  263. struct list_head *ptr = NULL;
  264. struct list_head *next = NULL;
  265. struct dtmf_buf_node *buf_node = NULL;
  266. struct snd_dma_buffer *c_dma_buf;
  267. struct snd_pcm_substream *c_substream;
  268. struct snd_pcm_runtime *runtime = substream->runtime;
  269. struct dtmf_drv_info *prtd = runtime->private_data;
  270. unsigned long dsp_flags;
  271. pr_debug("%s() DTMF\n", __func__);
  272. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
  273. mutex_lock(&prtd->lock);
  274. wake_up(&prtd->out_wait);
  275. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  276. prtd->capture_instance--;
  277. if (!prtd->capture_instance) {
  278. if (prtd->state == DTMF_GEN_RX_STARTED) {
  279. prtd->state = DTMF_GEN_RX_STOPPED;
  280. voc_disable_dtmf_det_on_active_sessions();
  281. voc_register_dtmf_rx_detection_cb(NULL, NULL);
  282. }
  283. /* release all buffer */
  284. /* release out_queue and free_out_queue */
  285. pr_debug("release all buffer\n");
  286. c_substream = prtd->capture_substream;
  287. if (c_substream == NULL) {
  288. pr_debug("c_substream is NULL\n");
  289. mutex_unlock(&prtd->lock);
  290. return -EINVAL;
  291. }
  292. c_dma_buf = &c_substream->dma_buffer;
  293. if (c_dma_buf == NULL) {
  294. pr_debug("c_dma_buf is NULL.\n");
  295. mutex_unlock(&prtd->lock);
  296. return -EINVAL;
  297. }
  298. if (c_dma_buf->area != NULL) {
  299. spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
  300. list_for_each_safe(ptr, next,
  301. &prtd->out_queue) {
  302. buf_node = list_entry(ptr,
  303. struct dtmf_buf_node, list);
  304. list_del(&buf_node->list);
  305. }
  306. list_for_each_safe(ptr, next,
  307. &prtd->free_out_queue) {
  308. buf_node = list_entry(ptr,
  309. struct dtmf_buf_node, list);
  310. list_del(&buf_node->list);
  311. }
  312. spin_unlock_irqrestore(&prtd->dsp_lock,
  313. dsp_flags);
  314. dma_free_coherent(c_substream->pcm->card->dev,
  315. runtime->hw.buffer_bytes_max,
  316. c_dma_buf->area,
  317. c_dma_buf->addr);
  318. c_dma_buf->area = NULL;
  319. }
  320. }
  321. prtd->capture_substream = NULL;
  322. mutex_unlock(&prtd->lock);
  323. }
  324. return ret;
  325. }
  326. static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
  327. struct snd_pcm_hw_params *params)
  328. {
  329. struct snd_pcm_runtime *runtime = substream->runtime;
  330. struct dtmf_drv_info *prtd = runtime->private_data;
  331. struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
  332. struct dtmf_buf_node *buf_node = NULL;
  333. int i = 0, offset = 0;
  334. int ret = 0;
  335. pr_debug("%s: DTMF\n", __func__);
  336. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
  337. mutex_lock(&prtd->lock);
  338. dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
  339. dma_buf->dev.dev = substream->pcm->card->dev;
  340. dma_buf->private_data = NULL;
  341. dma_buf->area = dma_alloc_coherent(substream->pcm->card->dev,
  342. runtime->hw.buffer_bytes_max,
  343. &dma_buf->addr, GFP_KERNEL);
  344. if (!dma_buf->area) {
  345. pr_err("%s:MSM DTMF dma_alloc failed\n", __func__);
  346. mutex_unlock(&prtd->lock);
  347. return -ENOMEM;
  348. }
  349. dma_buf->bytes = runtime->hw.buffer_bytes_max;
  350. memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max);
  351. for (i = 0; i < DTMF_MAX_Q_LEN; i++) {
  352. pr_debug("node =%d\n", i);
  353. buf_node = (void *) dma_buf->area + offset;
  354. list_add_tail(&buf_node->list,
  355. &prtd->free_out_queue);
  356. offset = offset + sizeof(struct dtmf_buf_node);
  357. }
  358. snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
  359. mutex_unlock(&prtd->lock);
  360. }
  361. return ret;
  362. }
  363. static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
  364. {
  365. struct snd_pcm_runtime *runtime = substream->runtime;
  366. struct dtmf_drv_info *prtd = runtime->private_data;
  367. pr_debug("%s: DTMF\n", __func__);
  368. prtd->pcm_capture_size = snd_pcm_lib_buffer_bytes(substream);
  369. prtd->pcm_capture_count = snd_pcm_lib_period_bytes(substream);
  370. prtd->pcm_capture_irq_pos = 0;
  371. prtd->pcm_capture_buf_pos = 0;
  372. return 0;
  373. }
  374. static int msm_pcm_prepare(struct snd_pcm_substream *substream)
  375. {
  376. struct snd_pcm_runtime *runtime = substream->runtime;
  377. struct dtmf_drv_info *prtd = runtime->private_data;
  378. pr_debug("%s: DTMF\n", __func__);
  379. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
  380. mutex_lock(&prtd->lock);
  381. msm_pcm_capture_prepare(substream);
  382. if (runtime->format != FORMAT_S16_LE) {
  383. pr_err("format:%u doesn't match %d\n",
  384. (uint32_t)runtime->format, FORMAT_S16_LE);
  385. mutex_unlock(&prtd->lock);
  386. return -EINVAL;
  387. }
  388. if (prtd->capture_instance &&
  389. (prtd->state != DTMF_GEN_RX_STARTED)) {
  390. voc_register_dtmf_rx_detection_cb(dtmf_rx_detected_cb,
  391. prtd);
  392. prtd->state = DTMF_GEN_RX_STARTED;
  393. }
  394. mutex_unlock(&prtd->lock);
  395. }
  396. return 0;
  397. }
  398. static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
  399. {
  400. int ret = 0;
  401. struct snd_pcm_runtime *runtime = substream->runtime;
  402. struct dtmf_drv_info *prtd = runtime->private_data;
  403. switch (cmd) {
  404. case SNDRV_PCM_TRIGGER_START:
  405. case SNDRV_PCM_TRIGGER_RESUME:
  406. pr_debug("%s: Trigger start\n", __func__);
  407. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  408. prtd->capture_start = 1;
  409. break;
  410. case SNDRV_PCM_TRIGGER_STOP:
  411. pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
  412. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  413. prtd->capture_start = 0;
  414. break;
  415. default:
  416. ret = -EINVAL;
  417. break;
  418. }
  419. return ret;
  420. }
  421. static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
  422. {
  423. snd_pcm_uframes_t ret = 0;
  424. struct snd_pcm_runtime *runtime = substream->runtime;
  425. struct dtmf_drv_info *prtd = runtime->private_data;
  426. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
  427. if (prtd->pcm_capture_irq_pos >= prtd->pcm_capture_size)
  428. prtd->pcm_capture_irq_pos = 0;
  429. ret = bytes_to_frames(runtime, (prtd->pcm_capture_irq_pos));
  430. }
  431. return ret;
  432. }
  433. static const struct snd_pcm_ops msm_pcm_ops = {
  434. .open = msm_pcm_open,
  435. .copy_user = msm_pcm_copy,
  436. .hw_params = msm_pcm_hw_params,
  437. .close = msm_pcm_close,
  438. .prepare = msm_pcm_prepare,
  439. .trigger = msm_pcm_trigger,
  440. .pointer = msm_pcm_pointer,
  441. };
  442. static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
  443. {
  444. struct snd_card *card = rtd->card->snd_card;
  445. int ret = 0;
  446. if (!card->dev->coherent_dma_mask)
  447. card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  448. return ret;
  449. }
  450. static struct snd_soc_component_driver msm_soc_component = {
  451. .name = DRV_NAME,
  452. .ops = &msm_pcm_ops,
  453. .pcm_new = msm_asoc_pcm_new,
  454. .probe = msm_pcm_dtmf_probe,
  455. };
  456. static int msm_pcm_probe(struct platform_device *pdev)
  457. {
  458. pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
  459. return snd_soc_register_component(&pdev->dev,
  460. &msm_soc_component, NULL, 0);
  461. }
  462. static int msm_pcm_remove(struct platform_device *pdev)
  463. {
  464. snd_soc_unregister_component(&pdev->dev);
  465. return 0;
  466. }
  467. static const struct of_device_id msm_pcm_dtmf_dt_match[] = {
  468. {.compatible = "qcom,msm-pcm-dtmf"},
  469. {}
  470. };
  471. MODULE_DEVICE_TABLE(of, msm_pcm_dtmf_dt_match);
  472. static struct platform_driver msm_pcm_driver = {
  473. .driver = {
  474. .name = "msm-pcm-dtmf",
  475. .owner = THIS_MODULE,
  476. .of_match_table = msm_pcm_dtmf_dt_match,
  477. },
  478. .probe = msm_pcm_probe,
  479. .remove = msm_pcm_remove,
  480. };
  481. int __init msm_pcm_dtmf_init(void)
  482. {
  483. return platform_driver_register(&msm_pcm_driver);
  484. }
  485. void msm_pcm_dtmf_exit(void)
  486. {
  487. platform_driver_unregister(&msm_pcm_driver);
  488. }
  489. MODULE_DESCRIPTION("DTMF platform driver");
  490. MODULE_LICENSE("GPL v2");