msm-pcm-host-voice-v2.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  3. */
  4. #include <linux/init.h>
  5. #include <linux/err.h>
  6. #include <linux/module.h>
  7. #include <linux/time.h>
  8. #include <linux/wait.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/slab.h>
  11. #include <linux/dma-mapping.h>
  12. #include <sound/core.h>
  13. #include <sound/soc.h>
  14. #include <sound/soc-dapm.h>
  15. #include <sound/pcm.h>
  16. #include <sound/initval.h>
  17. #include <sound/control.h>
  18. #include <asm/dma.h>
  19. #include <dsp/msm_audio_ion.h>
  20. #include <dsp/q6voice.h>
  21. #define HPCM_MAX_Q_LEN 2
  22. #define HPCM_MIN_VOC_PKT_SIZE 320
  23. #define HPCM_MAX_VOC_PKT_SIZE 640
  24. #define VHPCM_BLOCK_SIZE 4096
  25. #define CACHE_ALIGNMENT_SIZE 128
  26. #define CACHE_ALIGNMENT_MASK 0xFFFFFF80
  27. #define VOICE_TX_CAPTURE_DAI_ID "CS-VOICE HOST TX CAPTURE"
  28. #define VOICE_TX_PLAYBACK_DAI_ID "CS-VOICE HOST TX PLAYBACK"
  29. #define VOICE_RX_CAPTURE_DAI_ID "CS-VOICE HOST RX CAPTURE"
  30. #define VOICE_RX_PLAYBACK_DAI_ID "CS-VOICE HOST RX PLAYBACK"
  31. #define VOLTE_TX_CAPTURE_DAI_ID "VOLTE HOST TX CAPTURE"
  32. #define VOLTE_TX_PLAYBACK_DAI_ID "VOLTE HOST TX PLAYBACK"
  33. #define VOLTE_RX_CAPTURE_DAI_ID "VOLTE HOST RX CAPTURE"
  34. #define VOLTE_RX_PLAYBACK_DAI_ID "VOLTE HOST RX PLAYBACK"
  35. #define VoMMode1_TX_CAPTURE_DAI_ID "VoiceMMode1 HOST TX CAPTURE"
  36. #define VoMMode1_TX_PLAYBACK_DAI_ID "VoiceMMode1 HOST TX PLAYBACK"
  37. #define VoMMode1_RX_CAPTURE_DAI_ID "VoiceMMode1 HOST RX CAPTURE"
  38. #define VoMMode1_RX_PLAYBACK_DAI_ID "VoiceMMode1 HOST RX PLAYBACK"
  39. #define VoMMode2_TX_CAPTURE_DAI_ID "VoiceMMode2 HOST TX CAPTURE"
  40. #define VoMMode2_TX_PLAYBACK_DAI_ID "VoiceMMode2 HOST TX PLAYBACK"
  41. #define VoMMode2_RX_CAPTURE_DAI_ID "VoiceMMode2 HOST RX CAPTURE"
  42. #define VoMMode2_RX_PLAYBACK_DAI_ID "VoiceMMode2 HOST RX PLAYBACK"
  43. enum {
  44. RX = 1,
  45. TX,
  46. };
  47. enum {
  48. VOICE_INDEX = 0,
  49. VOLTE_INDEX,
  50. VOMMODE1_INDEX,
  51. VOMMODE2_INDEX,
  52. MAX_SESSION
  53. };
  54. enum hpcm_state {
  55. HPCM_STOPPED = 1,
  56. HPCM_CLOSED,
  57. HPCM_PREPARED,
  58. HPCM_STARTED,
  59. };
  60. struct hpcm_frame {
  61. uint32_t len;
  62. uint8_t voc_pkt[HPCM_MAX_VOC_PKT_SIZE];
  63. };
  64. struct hpcm_buf_node {
  65. struct list_head list;
  66. struct hpcm_frame frame;
  67. };
  68. struct vocpcm_ion_buffer {
  69. /* Physical address */
  70. phys_addr_t paddr;
  71. /* Kernel virtual address */
  72. void *kvaddr;
  73. };
  74. struct dai_data {
  75. enum hpcm_state state;
  76. struct snd_pcm_substream *substream;
  77. struct list_head filled_queue;
  78. struct list_head free_queue;
  79. wait_queue_head_t queue_wait;
  80. spinlock_t dsp_lock;
  81. uint32_t pcm_size;
  82. uint32_t pcm_count;
  83. /* IRQ position */
  84. uint32_t pcm_irq_pos;
  85. /* Position in buffer */
  86. uint32_t pcm_buf_pos;
  87. struct vocpcm_ion_buffer vocpcm_ion_buffer;
  88. };
  89. struct tap_point {
  90. struct dai_data playback_dai_data;
  91. struct dai_data capture_dai_data;
  92. };
  93. struct session {
  94. struct tap_point tx_tap_point;
  95. struct tap_point rx_tap_point;
  96. phys_addr_t sess_paddr;
  97. void *sess_kvaddr;
  98. struct dma_buf *dma_buf;
  99. struct mem_map_table tp_mem_table;
  100. };
  101. struct tappnt_mxr_data {
  102. bool enable;
  103. uint16_t direction;
  104. uint16_t sample_rate;
  105. };
  106. /* Values from mixer ctl are cached in this structure */
  107. struct mixer_conf {
  108. int8_t sess_indx;
  109. struct tappnt_mxr_data rx;
  110. struct tappnt_mxr_data tx;
  111. };
  112. struct start_cmd {
  113. struct vss_ivpcm_tap_point tap_pnt[2];
  114. uint32_t no_of_tapoints;
  115. };
  116. struct hpcm_drv {
  117. struct mutex lock;
  118. struct session session[MAX_SESSION];
  119. struct mixer_conf mixer_conf;
  120. struct start_cmd start_cmd;
  121. };
  122. static struct hpcm_drv hpcm_drv;
  123. static struct snd_pcm_hardware msm_pcm_hardware = {
  124. .info = (SNDRV_PCM_INFO_MMAP |
  125. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  126. SNDRV_PCM_INFO_MMAP_VALID |
  127. SNDRV_PCM_INFO_INTERLEAVED),
  128. .formats = SNDRV_PCM_FMTBIT_S16_LE |
  129. SNDRV_PCM_FMTBIT_SPECIAL,
  130. .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
  131. .rate_min = 8000,
  132. .rate_max = 16000,
  133. .channels_min = 1,
  134. .channels_max = 1,
  135. .buffer_bytes_max = sizeof(struct hpcm_buf_node) * HPCM_MAX_Q_LEN,
  136. .period_bytes_min = HPCM_MIN_VOC_PKT_SIZE,
  137. .period_bytes_max = HPCM_MAX_VOC_PKT_SIZE,
  138. .periods_min = HPCM_MAX_Q_LEN,
  139. .periods_max = HPCM_MAX_Q_LEN,
  140. .fifo_size = 0,
  141. };
  142. static char *hpcm_get_sess_name(int sess_indx)
  143. {
  144. char *sess_name = NULL;
  145. if (sess_indx == VOICE_INDEX)
  146. sess_name = VOICE_SESSION_NAME;
  147. else if (sess_indx == VOLTE_INDEX)
  148. sess_name = VOLTE_SESSION_NAME;
  149. else if (sess_indx == VOMMODE1_INDEX)
  150. sess_name = VOICEMMODE1_NAME;
  151. else if (sess_indx == VOMMODE2_INDEX)
  152. sess_name = VOICEMMODE2_NAME;
  153. else
  154. pr_err("%s:, Invalid sess_index\n", __func__);
  155. return sess_name;
  156. }
  157. static void hpcm_reset_mixer_config(struct hpcm_drv *prtd)
  158. {
  159. prtd->mixer_conf.sess_indx = -1;
  160. prtd->mixer_conf.rx.enable = false;
  161. prtd->mixer_conf.rx.direction = -1;
  162. prtd->mixer_conf.rx.sample_rate = 0;
  163. prtd->mixer_conf.tx.enable = false;
  164. prtd->mixer_conf.tx.direction = -1;
  165. prtd->mixer_conf.tx.sample_rate = 0;
  166. }
  167. /* Check for valid mixer control values */
  168. static bool hpcm_is_valid_config(int sess_indx, int tap_point,
  169. uint16_t direction, uint16_t samplerate)
  170. {
  171. if (sess_indx < VOICE_INDEX || sess_indx > VOMMODE2_INDEX) {
  172. pr_err("%s: invalid sess_indx :%d\n", __func__, sess_indx);
  173. goto error;
  174. }
  175. if (samplerate != VSS_IVPCM_SAMPLING_RATE_8K &&
  176. samplerate != VSS_IVPCM_SAMPLING_RATE_16K) {
  177. pr_err("%s: invalid sample rate :%d\n", __func__, samplerate);
  178. goto error;
  179. }
  180. if ((tap_point != RX) && (tap_point != TX)) {
  181. pr_err("%s: invalid tappoint :%d\n", __func__, tap_point);
  182. goto error;
  183. }
  184. if ((direction != VSS_IVPCM_TAP_POINT_DIR_IN) &&
  185. (direction != VSS_IVPCM_TAP_POINT_DIR_OUT) &&
  186. (direction != VSS_IVPCM_TAP_POINT_DIR_OUT_IN)) {
  187. pr_err("%s: invalid direction :%d\n", __func__, direction);
  188. goto error;
  189. }
  190. return true;
  191. error:
  192. return false;
  193. }
  194. static struct dai_data *hpcm_get_dai_data(char *pcm_id, struct hpcm_drv *prtd)
  195. {
  196. struct dai_data *dai_data = NULL;
  197. size_t size = 0;
  198. if (pcm_id) {
  199. size = strlen(pcm_id);
  200. /* Check for Voice DAI */
  201. if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, size)) {
  202. dai_data =
  203. &prtd->session[VOICE_INDEX].tx_tap_point.capture_dai_data;
  204. } else if (strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, size)) {
  205. dai_data =
  206. &prtd->session[VOICE_INDEX].tx_tap_point.playback_dai_data;
  207. } else if (strnstr(pcm_id, VOICE_RX_CAPTURE_DAI_ID, size)) {
  208. dai_data =
  209. &prtd->session[VOICE_INDEX].rx_tap_point.capture_dai_data;
  210. } else if (strnstr(pcm_id, VOICE_RX_PLAYBACK_DAI_ID, size)) {
  211. dai_data =
  212. &prtd->session[VOICE_INDEX].rx_tap_point.playback_dai_data;
  213. /* Check for VoLTE DAI */
  214. } else if (strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, size)) {
  215. dai_data =
  216. &prtd->session[VOLTE_INDEX].tx_tap_point.capture_dai_data;
  217. } else if (strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, size)) {
  218. dai_data =
  219. &prtd->session[VOLTE_INDEX].tx_tap_point.playback_dai_data;
  220. } else if (strnstr(pcm_id, VOLTE_RX_CAPTURE_DAI_ID, size)) {
  221. dai_data =
  222. &prtd->session[VOLTE_INDEX].rx_tap_point.capture_dai_data;
  223. } else if (strnstr(pcm_id, VOLTE_RX_PLAYBACK_DAI_ID, size)) {
  224. dai_data =
  225. &prtd->session[VOLTE_INDEX].rx_tap_point.playback_dai_data;
  226. /* check for VoiceMMode1 DAI */
  227. } else if (strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, size)) {
  228. dai_data =
  229. &prtd->session[VOMMODE1_INDEX].tx_tap_point.capture_dai_data;
  230. } else if (strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, size)) {
  231. dai_data =
  232. &prtd->session[VOMMODE1_INDEX].tx_tap_point.playback_dai_data;
  233. } else if (strnstr(pcm_id, VoMMode1_RX_CAPTURE_DAI_ID, size)) {
  234. dai_data =
  235. &prtd->session[VOMMODE1_INDEX].rx_tap_point.capture_dai_data;
  236. } else if (strnstr(pcm_id, VoMMode1_RX_PLAYBACK_DAI_ID, size)) {
  237. dai_data =
  238. &prtd->session[VOMMODE1_INDEX].rx_tap_point.playback_dai_data;
  239. /* check for VOiceMMode2 DAI */
  240. } else if (strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, size)) {
  241. dai_data =
  242. &prtd->session[VOMMODE2_INDEX].tx_tap_point.capture_dai_data;
  243. } else if (strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, size)) {
  244. dai_data =
  245. &prtd->session[VOMMODE2_INDEX].tx_tap_point.playback_dai_data;
  246. } else if (strnstr(pcm_id, VoMMode2_RX_CAPTURE_DAI_ID, size)) {
  247. dai_data =
  248. &prtd->session[VOMMODE2_INDEX].rx_tap_point.capture_dai_data;
  249. } else if (strnstr(pcm_id, VoMMode2_RX_PLAYBACK_DAI_ID, size)) {
  250. dai_data =
  251. &prtd->session[VOMMODE2_INDEX].rx_tap_point.playback_dai_data;
  252. } else {
  253. pr_err("%s: Wrong dai id\n", __func__);
  254. }
  255. }
  256. return dai_data;
  257. }
  258. static struct tap_point *hpcm_get_tappoint_data(char *pcm_id,
  259. struct hpcm_drv *prtd)
  260. {
  261. struct tap_point *tp = NULL;
  262. size_t size = 0;
  263. if (pcm_id) {
  264. size = strlen(pcm_id);
  265. /* Check for Voice DAI */
  266. if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, size)) {
  267. tp = &prtd->session[VOICE_INDEX].tx_tap_point;
  268. } else if (strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, size)) {
  269. tp = &prtd->session[VOICE_INDEX].tx_tap_point;
  270. } else if (strnstr(pcm_id, VOICE_RX_CAPTURE_DAI_ID, size)) {
  271. tp = &prtd->session[VOICE_INDEX].rx_tap_point;
  272. } else if (strnstr(pcm_id, VOICE_RX_PLAYBACK_DAI_ID, size)) {
  273. tp = &prtd->session[VOICE_INDEX].rx_tap_point;
  274. /* Check for VoLTE DAI */
  275. } else if (strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, size)) {
  276. tp = &prtd->session[VOLTE_INDEX].tx_tap_point;
  277. } else if (strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, size)) {
  278. tp = &prtd->session[VOLTE_INDEX].tx_tap_point;
  279. } else if (strnstr(pcm_id, VOLTE_RX_CAPTURE_DAI_ID, size)) {
  280. tp = &prtd->session[VOLTE_INDEX].rx_tap_point;
  281. } else if (strnstr(pcm_id, VOLTE_RX_PLAYBACK_DAI_ID, size)) {
  282. tp = &prtd->session[VOLTE_INDEX].rx_tap_point;
  283. /* check for VoiceMMode1 */
  284. } else if (strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, size)) {
  285. tp = &prtd->session[VOMMODE1_INDEX].tx_tap_point;
  286. } else if (strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, size)) {
  287. tp = &prtd->session[VOMMODE1_INDEX].tx_tap_point;
  288. } else if (strnstr(pcm_id, VoMMode1_RX_CAPTURE_DAI_ID, size)) {
  289. tp = &prtd->session[VOMMODE1_INDEX].rx_tap_point;
  290. } else if (strnstr(pcm_id, VoMMode1_RX_PLAYBACK_DAI_ID, size)) {
  291. tp = &prtd->session[VOMMODE1_INDEX].rx_tap_point;
  292. /* check for VoiceMMode2 */
  293. } else if (strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, size)) {
  294. tp = &prtd->session[VOMMODE2_INDEX].tx_tap_point;
  295. } else if (strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, size)) {
  296. tp = &prtd->session[VOMMODE2_INDEX].tx_tap_point;
  297. } else if (strnstr(pcm_id, VoMMode2_RX_CAPTURE_DAI_ID, size)) {
  298. tp = &prtd->session[VOMMODE2_INDEX].rx_tap_point;
  299. } else if (strnstr(pcm_id, VoMMode2_RX_PLAYBACK_DAI_ID, size)) {
  300. tp = &prtd->session[VOMMODE2_INDEX].rx_tap_point;
  301. } else {
  302. pr_err("%s: wrong dai id\n", __func__);
  303. }
  304. }
  305. return tp;
  306. }
  307. static struct tappnt_mxr_data *hpcm_get_tappnt_mixer_data(char *pcm_id,
  308. struct hpcm_drv *prtd)
  309. {
  310. if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
  311. strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
  312. strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
  313. strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
  314. strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
  315. strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
  316. strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
  317. strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) {
  318. return &prtd->mixer_conf.tx;
  319. } else {
  320. return &prtd->mixer_conf.rx;
  321. }
  322. }
  323. static int get_tappnt_value(char *pcm_id)
  324. {
  325. if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
  326. strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
  327. strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
  328. strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
  329. strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
  330. strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) ||
  331. strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, strlen(pcm_id)) ||
  332. strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) {
  333. return TX;
  334. } else {
  335. return RX;
  336. }
  337. }
  338. static bool hpcm_all_dais_are_ready(uint16_t direction, struct tap_point *tp,
  339. enum hpcm_state state)
  340. {
  341. bool dais_started = false;
  342. /*
  343. * Based on the direction set per tap point in the mixer control,
  344. * all the dais per tap point should meet the required state for the
  345. * commands such as vpcm_map_memory/vpcm_start to be executed.
  346. */
  347. switch (direction) {
  348. case VSS_IVPCM_TAP_POINT_DIR_OUT_IN:
  349. if ((tp->playback_dai_data.state >= state) &&
  350. (tp->capture_dai_data.state >= state)) {
  351. dais_started = true;
  352. }
  353. break;
  354. case VSS_IVPCM_TAP_POINT_DIR_IN:
  355. if (tp->playback_dai_data.state >= state)
  356. dais_started = true;
  357. break;
  358. case VSS_IVPCM_TAP_POINT_DIR_OUT:
  359. if (tp->capture_dai_data.state >= state)
  360. dais_started = true;
  361. break;
  362. default:
  363. pr_err("invalid direction\n");
  364. }
  365. return dais_started;
  366. }
  367. static void hpcm_create_free_queue(struct snd_dma_buffer *dma_buf,
  368. struct dai_data *dai_data)
  369. {
  370. struct hpcm_buf_node *buf_node = NULL;
  371. int i = 0, offset = 0;
  372. for (i = 0; i < HPCM_MAX_Q_LEN; i++) {
  373. buf_node = (void *)dma_buf->area + offset;
  374. list_add_tail(&buf_node->list,
  375. &dai_data->free_queue);
  376. offset = offset + sizeof(struct hpcm_buf_node);
  377. }
  378. }
  379. static void hpcm_free_allocated_mem(struct hpcm_drv *prtd)
  380. {
  381. phys_addr_t paddr = 0;
  382. struct tap_point *txtp = NULL;
  383. struct tap_point *rxtp = NULL;
  384. struct session *sess = NULL;
  385. sess = &prtd->session[prtd->mixer_conf.sess_indx];
  386. txtp = &sess->tx_tap_point;
  387. rxtp = &sess->rx_tap_point;
  388. paddr = sess->sess_paddr;
  389. if (paddr) {
  390. msm_audio_ion_free(sess->dma_buf);
  391. sess->dma_buf = NULL;
  392. msm_audio_ion_free(sess->tp_mem_table.dma_buf);
  393. sess->tp_mem_table.dma_buf = NULL;
  394. sess->sess_paddr = 0;
  395. sess->sess_kvaddr = 0;
  396. txtp->capture_dai_data.vocpcm_ion_buffer.paddr = 0;
  397. txtp->capture_dai_data.vocpcm_ion_buffer.kvaddr = 0;
  398. txtp->playback_dai_data.vocpcm_ion_buffer.paddr = 0;
  399. txtp->playback_dai_data.vocpcm_ion_buffer.kvaddr = 0;
  400. rxtp->capture_dai_data.vocpcm_ion_buffer.paddr = 0;
  401. rxtp->capture_dai_data.vocpcm_ion_buffer.kvaddr = 0;
  402. rxtp->playback_dai_data.vocpcm_ion_buffer.paddr = 0;
  403. rxtp->playback_dai_data.vocpcm_ion_buffer.kvaddr = 0;
  404. } else {
  405. pr_debug("%s, paddr = 0, nothing to free\n", __func__);
  406. }
  407. }
  408. static void hpcm_unmap_and_free_shared_memory(struct hpcm_drv *prtd)
  409. {
  410. phys_addr_t paddr = 0;
  411. char *sess_name = hpcm_get_sess_name(prtd->mixer_conf.sess_indx);
  412. if (prtd->mixer_conf.sess_indx >= 0)
  413. paddr = prtd->session[prtd->mixer_conf.sess_indx].sess_paddr;
  414. else
  415. paddr = 0;
  416. if (paddr) {
  417. voc_send_cvp_unmap_vocpcm_memory(voc_get_session_id(sess_name));
  418. hpcm_free_allocated_mem(prtd);
  419. } else {
  420. pr_debug("%s, paddr = 0, nothing to unmap/free\n", __func__);
  421. }
  422. }
  423. static int hpcm_map_vocpcm_memory(struct hpcm_drv *prtd)
  424. {
  425. int ret = 0;
  426. char *sess_name = hpcm_get_sess_name(prtd->mixer_conf.sess_indx);
  427. struct session *sess = NULL;
  428. sess = &prtd->session[prtd->mixer_conf.sess_indx];
  429. ret = voc_send_cvp_map_vocpcm_memory(voc_get_session_id(sess_name),
  430. &sess->tp_mem_table,
  431. sess->sess_paddr,
  432. VHPCM_BLOCK_SIZE);
  433. return ret;
  434. }
  435. static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd)
  436. {
  437. int result;
  438. int ret = 0;
  439. size_t mem_len;
  440. size_t len;
  441. struct tap_point *txtp = NULL;
  442. struct tap_point *rxtp = NULL;
  443. struct session *sess = NULL;
  444. sess = &prtd->session[prtd->mixer_conf.sess_indx];
  445. txtp = &sess->tx_tap_point;
  446. rxtp = &sess->rx_tap_point;
  447. result = msm_audio_ion_alloc(&sess->dma_buf,
  448. VHPCM_BLOCK_SIZE,
  449. &sess->sess_paddr,
  450. &mem_len,
  451. &sess->sess_kvaddr);
  452. if (result) {
  453. pr_err("%s: msm_audio_ion_alloc error, rc = %d\n",
  454. __func__, result);
  455. sess->sess_paddr = 0;
  456. sess->sess_kvaddr = 0;
  457. ret = -ENOMEM;
  458. goto done;
  459. }
  460. pr_debug("%s: Host PCM memory block allocated\n", __func__);
  461. /* Allocate mem_map_table for tap point */
  462. result = msm_audio_ion_alloc(&sess->tp_mem_table.dma_buf,
  463. sizeof(struct vss_imemory_table_t),
  464. &sess->tp_mem_table.phys,
  465. &len,
  466. &sess->tp_mem_table.data);
  467. if (result) {
  468. pr_err("%s: msm_audio_ion_alloc error, rc = %d\n",
  469. __func__, result);
  470. msm_audio_ion_free(sess->dma_buf);
  471. sess->dma_buf = NULL;
  472. sess->sess_paddr = 0;
  473. sess->sess_kvaddr = 0;
  474. ret = -ENOMEM;
  475. goto done;
  476. }
  477. pr_debug("%s: Host PCM memory table allocated\n", __func__);
  478. memset(sess->tp_mem_table.data, 0,
  479. sizeof(struct vss_imemory_table_t));
  480. sess->tp_mem_table.size = sizeof(struct vss_imemory_table_t);
  481. pr_debug("%s: data %pK phys %pK\n", __func__,
  482. sess->tp_mem_table.data, &sess->tp_mem_table.phys);
  483. /* Split 4096 block into four 1024 byte blocks for each dai */
  484. txtp->capture_dai_data.vocpcm_ion_buffer.paddr =
  485. sess->sess_paddr;
  486. txtp->capture_dai_data.vocpcm_ion_buffer.kvaddr =
  487. sess->sess_kvaddr;
  488. txtp->playback_dai_data.vocpcm_ion_buffer.paddr =
  489. sess->sess_paddr + VHPCM_BLOCK_SIZE/4;
  490. txtp->playback_dai_data.vocpcm_ion_buffer.kvaddr =
  491. sess->sess_kvaddr + VHPCM_BLOCK_SIZE/4;
  492. rxtp->capture_dai_data.vocpcm_ion_buffer.paddr =
  493. sess->sess_paddr + (VHPCM_BLOCK_SIZE/4) * 2;
  494. rxtp->capture_dai_data.vocpcm_ion_buffer.kvaddr =
  495. sess->sess_kvaddr + (VHPCM_BLOCK_SIZE/4) * 2;
  496. rxtp->playback_dai_data.vocpcm_ion_buffer.paddr =
  497. sess->sess_paddr + (VHPCM_BLOCK_SIZE/4) * 3;
  498. rxtp->playback_dai_data.vocpcm_ion_buffer.kvaddr =
  499. sess->sess_kvaddr + (VHPCM_BLOCK_SIZE/4) * 3;
  500. done:
  501. return ret;
  502. }
  503. static int hpcm_start_vocpcm(char *pcm_id, struct hpcm_drv *prtd,
  504. struct tap_point *tp)
  505. {
  506. int indx = prtd->mixer_conf.sess_indx;
  507. uint32_t *no_of_tp = &prtd->start_cmd.no_of_tapoints;
  508. struct vss_ivpcm_tap_point *tap_pnt = &prtd->start_cmd.tap_pnt[0];
  509. uint32_t no_of_tp_req = 0;
  510. char *sess_name = hpcm_get_sess_name(indx);
  511. if (prtd->mixer_conf.rx.enable)
  512. no_of_tp_req++;
  513. if (prtd->mixer_conf.tx.enable)
  514. no_of_tp_req++;
  515. if (prtd->mixer_conf.rx.enable && (get_tappnt_value(pcm_id) == RX)) {
  516. if (hpcm_all_dais_are_ready(prtd->mixer_conf.rx.direction,
  517. tp, HPCM_PREPARED)) {
  518. pr_debug("%s: RX conditions met\n", __func__);
  519. tap_pnt[*no_of_tp].tap_point =
  520. VSS_IVPCM_TAP_POINT_RX_DEFAULT;
  521. tap_pnt[*no_of_tp].direction =
  522. prtd->mixer_conf.rx.direction;
  523. tap_pnt[*no_of_tp].sampling_rate =
  524. prtd->mixer_conf.rx.sample_rate;
  525. (*no_of_tp)++;
  526. }
  527. }
  528. if (prtd->mixer_conf.tx.enable && (get_tappnt_value(pcm_id) == TX)) {
  529. if (hpcm_all_dais_are_ready(prtd->mixer_conf.tx.direction,
  530. tp, HPCM_PREPARED)) {
  531. pr_debug("%s: TX conditions met\n", __func__);
  532. tap_pnt[*no_of_tp].tap_point =
  533. VSS_IVPCM_TAP_POINT_TX_DEFAULT;
  534. tap_pnt[*no_of_tp].direction =
  535. prtd->mixer_conf.tx.direction;
  536. tap_pnt[*no_of_tp].sampling_rate =
  537. prtd->mixer_conf.tx.sample_rate;
  538. (*no_of_tp)++;
  539. }
  540. }
  541. if ((prtd->mixer_conf.tx.enable || prtd->mixer_conf.rx.enable) &&
  542. *no_of_tp == no_of_tp_req) {
  543. voc_send_cvp_start_vocpcm(voc_get_session_id(sess_name),
  544. tap_pnt, *no_of_tp);
  545. /* Reset the start command so that it is not called twice */
  546. memset(&prtd->start_cmd, 0, sizeof(struct start_cmd));
  547. } else {
  548. pr_debug("%s: required pcm handles not opened yet\n", __func__);
  549. }
  550. return 0;
  551. }
  552. /* Playback path*/
  553. static void hpcm_copy_playback_data_from_queue(struct dai_data *dai_data,
  554. uint32_t *len)
  555. {
  556. struct hpcm_buf_node *buf_node = NULL;
  557. unsigned long dsp_flags;
  558. if (dai_data->substream == NULL)
  559. return;
  560. spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
  561. if (!list_empty(&dai_data->filled_queue)) {
  562. buf_node = list_first_entry(&dai_data->filled_queue,
  563. struct hpcm_buf_node, list);
  564. list_del(&buf_node->list);
  565. *len = buf_node->frame.len;
  566. memcpy((u8 *)dai_data->vocpcm_ion_buffer.kvaddr,
  567. &buf_node->frame.voc_pkt[0],
  568. buf_node->frame.len);
  569. list_add_tail(&buf_node->list, &dai_data->free_queue);
  570. dai_data->pcm_irq_pos += dai_data->pcm_count;
  571. spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
  572. snd_pcm_period_elapsed(dai_data->substream);
  573. } else {
  574. *len = 0;
  575. spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
  576. pr_err("IN data not available\n");
  577. }
  578. wake_up(&dai_data->queue_wait);
  579. }
  580. /* Capture path*/
  581. static void hpcm_copy_capture_data_to_queue(struct dai_data *dai_data,
  582. uint32_t len)
  583. {
  584. struct hpcm_buf_node *buf_node = NULL;
  585. unsigned long dsp_flags;
  586. if (dai_data->substream == NULL)
  587. return;
  588. /* Copy out buffer packet into free_queue */
  589. spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
  590. if (!list_empty(&dai_data->free_queue)) {
  591. buf_node = list_first_entry(&dai_data->free_queue,
  592. struct hpcm_buf_node, list);
  593. list_del(&buf_node->list);
  594. buf_node->frame.len = len;
  595. memcpy(&buf_node->frame.voc_pkt[0],
  596. (uint8_t *)dai_data->vocpcm_ion_buffer.kvaddr,
  597. buf_node->frame.len);
  598. list_add_tail(&buf_node->list, &dai_data->filled_queue);
  599. dai_data->pcm_irq_pos += dai_data->pcm_count;
  600. spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
  601. snd_pcm_period_elapsed(dai_data->substream);
  602. } else {
  603. spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
  604. pr_err("OUTPUT data dropped\n");
  605. }
  606. wake_up(&dai_data->queue_wait);
  607. }
  608. void hpcm_notify_evt_processing(uint8_t *data, char *session,
  609. void *private_data)
  610. {
  611. struct hpcm_drv *prtd = (struct hpcm_drv *)private_data;
  612. struct vss_ivpcm_evt_notify_v2_t *notify_evt =
  613. (struct vss_ivpcm_evt_notify_v2_t *)data;
  614. struct vss_ivpcm_evt_push_buffer_v2_t push_buff_event;
  615. struct tap_point *tp = NULL;
  616. int in_buf_len = 0;
  617. struct tappnt_mxr_data *tmd = NULL;
  618. char *sess_name = hpcm_get_sess_name(prtd->mixer_conf.sess_indx);
  619. /* If it's not a timetick, it's a error notification, drop the event */
  620. if ((notify_evt->notify_mask & VSS_IVPCM_NOTIFY_MASK_TIMETICK) == 0) {
  621. pr_err("%s: Error notification. mask=%d\n", __func__,
  622. notify_evt->notify_mask);
  623. return;
  624. }
  625. if (notify_evt->tap_point == VSS_IVPCM_TAP_POINT_TX_DEFAULT) {
  626. tp = &prtd->session[prtd->mixer_conf.sess_indx].tx_tap_point;
  627. tmd = &prtd->mixer_conf.tx;
  628. } else if (notify_evt->tap_point == VSS_IVPCM_TAP_POINT_RX_DEFAULT) {
  629. tp = &prtd->session[prtd->mixer_conf.sess_indx].rx_tap_point;
  630. tmd = &prtd->mixer_conf.rx;
  631. }
  632. if (tp == NULL || tmd == NULL) {
  633. pr_err("%s: tp = %pK or tmd = %pK is null\n", __func__,
  634. tp, tmd);
  635. return;
  636. }
  637. if (notify_evt->notify_mask & VSS_IVPCM_NOTIFY_MASK_OUTPUT_BUFFER) {
  638. hpcm_copy_capture_data_to_queue(&tp->capture_dai_data,
  639. notify_evt->filled_out_size);
  640. }
  641. if (notify_evt->notify_mask & VSS_IVPCM_NOTIFY_MASK_INPUT_BUFFER) {
  642. hpcm_copy_playback_data_from_queue(&tp->playback_dai_data,
  643. &in_buf_len);
  644. }
  645. switch (tmd->direction) {
  646. /*
  647. * When the dir is OUT_IN, for the first notify mask, pushbuf mask
  648. * should be set to VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER since we
  649. * atleast need one buffer's worth data before we can send IN buffer.
  650. * For the consecutive notify evts, the push buf mask will set for both
  651. * VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER and
  652. * VSS_IVPCM_PUSH_BUFFER_MASK_IN_BUFFER.
  653. */
  654. case VSS_IVPCM_TAP_POINT_DIR_OUT_IN:
  655. if (notify_evt->notify_mask ==
  656. VSS_IVPCM_NOTIFY_MASK_TIMETICK) {
  657. push_buff_event.push_buf_mask =
  658. VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER;
  659. } else {
  660. push_buff_event.push_buf_mask =
  661. VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER |
  662. VSS_IVPCM_PUSH_BUFFER_MASK_INPUT_BUFFER;
  663. }
  664. break;
  665. case VSS_IVPCM_TAP_POINT_DIR_IN:
  666. push_buff_event.push_buf_mask =
  667. VSS_IVPCM_PUSH_BUFFER_MASK_INPUT_BUFFER;
  668. break;
  669. case VSS_IVPCM_TAP_POINT_DIR_OUT:
  670. push_buff_event.push_buf_mask =
  671. VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER;
  672. break;
  673. }
  674. push_buff_event.tap_point = notify_evt->tap_point;
  675. push_buff_event.out_buf_mem_address =
  676. tp->capture_dai_data.vocpcm_ion_buffer.paddr;
  677. push_buff_event.in_buf_mem_address =
  678. tp->playback_dai_data.vocpcm_ion_buffer.paddr;
  679. push_buff_event.sampling_rate = notify_evt->sampling_rate;
  680. push_buff_event.num_in_channels = 1;
  681. /*
  682. * ADSP must read and write from a cache aligned (128 byte) location,
  683. * and in blocks of the cache alignment size. The 128 byte cache
  684. * alignment requirement is guaranteed due to 4096 byte memory
  685. * alignment requirement during memory allocation/mapping. The output
  686. * buffer (ADSP write) size mask ensures that a 128 byte multiple
  687. * worth of will be written. Internally, the input buffer (ADSP read)
  688. * size will also be a multiple of 128 bytes. However it is the
  689. * application's responsibility to ensure no other data is written in
  690. * the specified length of memory.
  691. */
  692. push_buff_event.out_buf_mem_size = ((notify_evt->request_buf_size) +
  693. CACHE_ALIGNMENT_SIZE) & CACHE_ALIGNMENT_MASK;
  694. push_buff_event.in_buf_mem_size = in_buf_len;
  695. voc_send_cvp_vocpcm_push_buf_evt(voc_get_session_id(sess_name),
  696. &push_buff_event);
  697. }
  698. static int msm_hpcm_configure_voice_put(struct snd_kcontrol *kcontrol,
  699. struct snd_ctl_elem_value *ucontrol)
  700. {
  701. int tap_point = ucontrol->value.integer.value[0];
  702. uint16_t direction = ucontrol->value.integer.value[1];
  703. uint16_t sample_rate = ucontrol->value.integer.value[2];
  704. struct tappnt_mxr_data *tmd = NULL;
  705. int ret = 0;
  706. mutex_lock(&hpcm_drv.lock);
  707. pr_debug("%s: tap_point = %d direction = %d sample_rate = %d\n",
  708. __func__, tap_point, direction, sample_rate);
  709. if (!hpcm_is_valid_config(VOICE_INDEX, tap_point, direction,
  710. sample_rate)) {
  711. pr_err("Invalid vpcm mixer control voice values\n");
  712. ret = -EINVAL;
  713. goto done;
  714. }
  715. if (tap_point == RX)
  716. tmd = &hpcm_drv.mixer_conf.rx;
  717. else
  718. tmd = &hpcm_drv.mixer_conf.tx;
  719. tmd->enable = true;
  720. tmd->direction = direction;
  721. tmd->sample_rate = sample_rate;
  722. hpcm_drv.mixer_conf.sess_indx = VOICE_INDEX;
  723. done:
  724. mutex_unlock(&hpcm_drv.lock);
  725. return ret;
  726. }
  727. static int msm_hpcm_configure_vmmode1_put(struct snd_kcontrol *kcontrol,
  728. struct snd_ctl_elem_value *ucontrol)
  729. {
  730. int tap_point = ucontrol->value.integer.value[0];
  731. uint16_t direction = ucontrol->value.integer.value[1];
  732. uint16_t sample_rate = ucontrol->value.integer.value[2];
  733. struct tappnt_mxr_data *tmd = NULL;
  734. int ret = 0;
  735. mutex_lock(&hpcm_drv.lock);
  736. pr_debug("%s: tap_point = %d direction = %d sample_rate = %d\n",
  737. __func__, tap_point, direction, sample_rate);
  738. if (!hpcm_is_valid_config(VOMMODE1_INDEX, tap_point, direction,
  739. sample_rate)) {
  740. pr_err("Invalid vpcm mixer control voice values\n");
  741. ret = -EINVAL;
  742. goto done;
  743. }
  744. if (tap_point == RX)
  745. tmd = &hpcm_drv.mixer_conf.rx;
  746. else
  747. tmd = &hpcm_drv.mixer_conf.tx;
  748. tmd->enable = true;
  749. tmd->direction = direction;
  750. tmd->sample_rate = sample_rate;
  751. hpcm_drv.mixer_conf.sess_indx = VOMMODE1_INDEX;
  752. done:
  753. mutex_unlock(&hpcm_drv.lock);
  754. return ret;
  755. }
  756. static int msm_hpcm_configure_vmmode2_put(struct snd_kcontrol *kcontrol,
  757. struct snd_ctl_elem_value *ucontrol)
  758. {
  759. int tap_point = ucontrol->value.integer.value[0];
  760. uint16_t direction = ucontrol->value.integer.value[1];
  761. uint16_t sample_rate = ucontrol->value.integer.value[2];
  762. struct tappnt_mxr_data *tmd = NULL;
  763. int ret = 0;
  764. mutex_lock(&hpcm_drv.lock);
  765. pr_debug("%s: tap_point = %d direction = %d sample_rate = %d\n",
  766. __func__, tap_point, direction, sample_rate);
  767. if (!hpcm_is_valid_config(VOMMODE2_INDEX, tap_point, direction,
  768. sample_rate)) {
  769. pr_err("Invalid vpcm mixer control voice values\n");
  770. ret = -EINVAL;
  771. goto done;
  772. }
  773. if (tap_point == RX)
  774. tmd = &hpcm_drv.mixer_conf.rx;
  775. else
  776. tmd = &hpcm_drv.mixer_conf.tx;
  777. tmd->enable = true;
  778. tmd->direction = direction;
  779. tmd->sample_rate = sample_rate;
  780. hpcm_drv.mixer_conf.sess_indx = VOMMODE2_INDEX;
  781. done:
  782. mutex_unlock(&hpcm_drv.lock);
  783. return ret;
  784. }
  785. static int msm_hpcm_configure_volte_put(struct snd_kcontrol *kcontrol,
  786. struct snd_ctl_elem_value *ucontrol)
  787. {
  788. int tap_point = ucontrol->value.integer.value[0];
  789. uint16_t direction = ucontrol->value.integer.value[1];
  790. uint16_t sample_rate = ucontrol->value.integer.value[2];
  791. struct tappnt_mxr_data *tmd = NULL;
  792. int ret = 0;
  793. mutex_lock(&hpcm_drv.lock);
  794. pr_debug("%s: tap_point=%d direction=%d sample_rate=%d\n",
  795. __func__, tap_point, direction, sample_rate);
  796. if (!hpcm_is_valid_config(VOLTE_INDEX, tap_point, direction,
  797. sample_rate)) {
  798. pr_err("Invalid vpcm mixer control volte values\n");
  799. ret = -EINVAL;
  800. goto done;
  801. }
  802. if (tap_point == RX)
  803. tmd = &hpcm_drv.mixer_conf.rx;
  804. else
  805. tmd = &hpcm_drv.mixer_conf.tx;
  806. tmd->enable = true;
  807. tmd->direction = direction;
  808. tmd->sample_rate = sample_rate;
  809. hpcm_drv.mixer_conf.sess_indx = VOLTE_INDEX;
  810. done:
  811. mutex_unlock(&hpcm_drv.lock);
  812. return ret;
  813. }
  814. static struct snd_kcontrol_new msm_hpcm_controls[] = {
  815. SOC_SINGLE_MULTI_EXT("HPCM_Voice tappoint direction samplerate",
  816. SND_SOC_NOPM, 0, 16000, 0, 3,
  817. NULL, msm_hpcm_configure_voice_put),
  818. SOC_SINGLE_MULTI_EXT("HPCM_VoLTE tappoint direction samplerate",
  819. SND_SOC_NOPM, 0, 16000, 0, 3,
  820. NULL, msm_hpcm_configure_volte_put),
  821. SOC_SINGLE_MULTI_EXT("HPCM_VMMode1 tappoint direction samplerate",
  822. SND_SOC_NOPM, 0, 16000, 0, 3,
  823. NULL, msm_hpcm_configure_vmmode1_put),
  824. SOC_SINGLE_MULTI_EXT("HPCM_VMMode2 tappoint direction samplerate",
  825. SND_SOC_NOPM, 0, 16000, 0, 3,
  826. NULL, msm_hpcm_configure_vmmode2_put),
  827. };
  828. /* Sample rates supported */
  829. static unsigned int supported_sample_rates[] = {8000, 16000};
  830. static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
  831. .count = ARRAY_SIZE(supported_sample_rates),
  832. .list = supported_sample_rates,
  833. .mask = 0,
  834. };
  835. static int msm_pcm_close(struct snd_pcm_substream *substream)
  836. {
  837. int ret = 0;
  838. struct list_head *ptr = NULL;
  839. struct list_head *next = NULL;
  840. struct hpcm_buf_node *buf_node = NULL;
  841. struct snd_dma_buffer *dma_buf;
  842. struct snd_pcm_runtime *runtime;
  843. struct hpcm_drv *prtd;
  844. unsigned long dsp_flags;
  845. struct dai_data *dai_data = NULL;
  846. struct tap_point *tp = NULL;
  847. struct tappnt_mxr_data *tmd = NULL;
  848. char *sess_name = NULL;
  849. if (substream == NULL) {
  850. pr_err("substream is NULL\n");
  851. return -EINVAL;
  852. }
  853. pr_debug("%s, %s\n", __func__, substream->pcm->id);
  854. runtime = substream->runtime;
  855. prtd = runtime->private_data;
  856. sess_name = hpcm_get_sess_name(prtd->mixer_conf.sess_indx);
  857. dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
  858. if (dai_data == NULL) {
  859. pr_err("%s, dai_data is NULL\n", __func__);
  860. ret = -EINVAL;
  861. goto done;
  862. }
  863. wake_up(&dai_data->queue_wait);
  864. mutex_lock(&prtd->lock);
  865. tmd = hpcm_get_tappnt_mixer_data(substream->pcm->id, prtd);
  866. tp = hpcm_get_tappoint_data(substream->pcm->id, prtd);
  867. /* Send stop command */
  868. voc_send_cvp_stop_vocpcm(voc_get_session_id(sess_name));
  869. /* Memory unmap/free takes place only when called the first time */
  870. hpcm_unmap_and_free_shared_memory(prtd);
  871. /* Unregister host PCM event callback function */
  872. voc_deregister_hpcm_evt_cb();
  873. /* Reset the cached start cmd */
  874. memset(&prtd->start_cmd, 0, sizeof(struct start_cmd));
  875. /* Release all buffer */
  876. pr_debug("%s: Release all buffer\n", __func__);
  877. substream = dai_data->substream;
  878. if (substream == NULL) {
  879. pr_debug("%s: substream is NULL\n", __func__);
  880. goto done;
  881. }
  882. dma_buf = &substream->dma_buffer;
  883. if (dma_buf == NULL) {
  884. pr_debug("%s: dma_buf is NULL\n", __func__);
  885. goto done;
  886. }
  887. if (dma_buf->area != NULL) {
  888. spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
  889. list_for_each_safe(ptr, next, &dai_data->filled_queue) {
  890. buf_node = list_entry(ptr,
  891. struct hpcm_buf_node, list);
  892. list_del(&buf_node->list);
  893. }
  894. list_for_each_safe(ptr, next, &dai_data->free_queue) {
  895. buf_node = list_entry(ptr,
  896. struct hpcm_buf_node, list);
  897. list_del(&buf_node->list);
  898. }
  899. spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
  900. dma_free_coherent(substream->pcm->card->dev,
  901. runtime->hw.buffer_bytes_max, dma_buf->area,
  902. dma_buf->addr);
  903. dma_buf->area = NULL;
  904. }
  905. dai_data->substream = NULL;
  906. dai_data->pcm_buf_pos = 0;
  907. dai_data->pcm_count = 0;
  908. dai_data->pcm_irq_pos = 0;
  909. dai_data->pcm_size = 0;
  910. dai_data->state = HPCM_CLOSED;
  911. hpcm_reset_mixer_config(prtd);
  912. done:
  913. mutex_unlock(&prtd->lock);
  914. return ret;
  915. }
  916. static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a,
  917. unsigned long hwoff, void __user *buf,
  918. unsigned long fbytes)
  919. {
  920. int ret = 0;
  921. struct hpcm_buf_node *buf_node = NULL;
  922. struct snd_pcm_runtime *runtime = substream->runtime;
  923. struct hpcm_drv *prtd = runtime->private_data;
  924. struct dai_data *dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
  925. unsigned long dsp_flags;
  926. if (dai_data == NULL) {
  927. pr_err("%s, dai_data is null\n", __func__);
  928. ret = -EINVAL;
  929. goto done;
  930. }
  931. ret = wait_event_interruptible_timeout(dai_data->queue_wait,
  932. (!list_empty(&dai_data->free_queue) ||
  933. dai_data->state == HPCM_STOPPED),
  934. 1 * HZ);
  935. if (ret > 0) {
  936. if (fbytes <= HPCM_MAX_VOC_PKT_SIZE) {
  937. spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
  938. buf_node =
  939. list_first_entry(&dai_data->free_queue,
  940. struct hpcm_buf_node, list);
  941. list_del(&buf_node->list);
  942. spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
  943. ret = copy_from_user(&buf_node->frame.voc_pkt, buf,
  944. fbytes);
  945. buf_node->frame.len = fbytes;
  946. spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
  947. list_add_tail(&buf_node->list, &dai_data->filled_queue);
  948. spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
  949. } else {
  950. pr_err("%s: Write cnt %lu is > HPCM_MAX_VOC_PKT_SIZE\n",
  951. __func__, fbytes);
  952. ret = -ENOMEM;
  953. }
  954. } else if (ret == 0) {
  955. pr_err("%s: No free Playback buffer\n", __func__);
  956. ret = -ETIMEDOUT;
  957. } else {
  958. pr_err("%s: playback copy was interrupted\n", __func__);
  959. }
  960. done:
  961. return ret;
  962. }
  963. static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
  964. int channel, unsigned long hwoff,
  965. void __user *buf, unsigned long fbytes)
  966. {
  967. int ret = 0;
  968. struct hpcm_buf_node *buf_node = NULL;
  969. struct snd_pcm_runtime *runtime = substream->runtime;
  970. struct hpcm_drv *prtd = runtime->private_data;
  971. struct dai_data *dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
  972. unsigned long dsp_flags;
  973. if (dai_data == NULL) {
  974. pr_err("%s, dai_data is null\n", __func__);
  975. ret = -EINVAL;
  976. goto done;
  977. }
  978. ret = wait_event_interruptible_timeout(dai_data->queue_wait,
  979. (!list_empty(&dai_data->filled_queue) ||
  980. dai_data->state == HPCM_STOPPED),
  981. 1 * HZ);
  982. if (ret > 0) {
  983. if (fbytes <= HPCM_MAX_VOC_PKT_SIZE) {
  984. spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
  985. buf_node = list_first_entry(&dai_data->filled_queue,
  986. struct hpcm_buf_node, list);
  987. list_del(&buf_node->list);
  988. spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
  989. ret = copy_to_user(buf, &buf_node->frame.voc_pkt,
  990. buf_node->frame.len);
  991. if (ret) {
  992. pr_err("%s: Copy to user returned %d\n",
  993. __func__, ret);
  994. ret = -EFAULT;
  995. }
  996. spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
  997. list_add_tail(&buf_node->list, &dai_data->free_queue);
  998. spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
  999. } else {
  1000. pr_err("%s: Read count %lu > HPCM_MAX_VOC_PKT_SIZE\n",
  1001. __func__, fbytes);
  1002. ret = -ENOMEM;
  1003. }
  1004. } else if (ret == 0) {
  1005. pr_err("%s: No Caputre data available\n", __func__);
  1006. ret = -ETIMEDOUT;
  1007. } else {
  1008. pr_err("%s: Read was interrupted\n", __func__);
  1009. ret = -ERESTARTSYS;
  1010. }
  1011. done:
  1012. return ret;
  1013. }
  1014. static int msm_pcm_copy(struct snd_pcm_substream *substream, int channel,
  1015. unsigned long hwoff, void __user *buf,
  1016. unsigned long fbytes)
  1017. {
  1018. int ret = 0;
  1019. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  1020. ret = msm_pcm_playback_copy(substream, channel,
  1021. hwoff, buf, fbytes);
  1022. else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  1023. ret = msm_pcm_capture_copy(substream, channel,
  1024. hwoff, buf, fbytes);
  1025. return ret;
  1026. }
  1027. static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
  1028. {
  1029. struct dai_data *dai_data = NULL;
  1030. struct snd_pcm_runtime *runtime = substream->runtime;
  1031. struct hpcm_drv *prtd = runtime->private_data;
  1032. snd_pcm_uframes_t ret;
  1033. dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
  1034. if (dai_data == NULL) {
  1035. pr_err("%s, dai_data is null\n", __func__);
  1036. ret = 0;
  1037. goto done;
  1038. }
  1039. if (dai_data->pcm_irq_pos >= dai_data->pcm_size)
  1040. dai_data->pcm_irq_pos = 0;
  1041. ret = bytes_to_frames(runtime, (dai_data->pcm_irq_pos));
  1042. done:
  1043. return ret;
  1044. }
  1045. static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
  1046. {
  1047. int ret = 0;
  1048. struct snd_pcm_runtime *runtime = substream->runtime;
  1049. struct hpcm_drv *prtd = runtime->private_data;
  1050. struct dai_data *dai_data =
  1051. hpcm_get_dai_data(substream->pcm->id, prtd);
  1052. if (dai_data == NULL) {
  1053. pr_err("%s, dai_data is null\n", __func__);
  1054. ret = -EINVAL;
  1055. goto done;
  1056. }
  1057. pr_debug("%s, %s\n", __func__, substream->pcm->id);
  1058. switch (cmd) {
  1059. case SNDRV_PCM_TRIGGER_START:
  1060. pr_debug("SNDRV_PCM_TRIGGER_START\n");
  1061. dai_data->state = HPCM_STARTED;
  1062. break;
  1063. case SNDRV_PCM_TRIGGER_STOP:
  1064. pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
  1065. dai_data->state = HPCM_STOPPED;
  1066. break;
  1067. default:
  1068. ret = -EINVAL;
  1069. break;
  1070. }
  1071. done:
  1072. return ret;
  1073. }
  1074. static int msm_pcm_prepare(struct snd_pcm_substream *substream)
  1075. {
  1076. int ret = 0;
  1077. struct snd_pcm_runtime *runtime = substream->runtime;
  1078. struct hpcm_drv *prtd = runtime->private_data;
  1079. struct dai_data *dai_data = NULL;
  1080. struct tap_point *tp = NULL;
  1081. pr_debug("%s, %s\n", __func__, substream->pcm->id);
  1082. mutex_lock(&prtd->lock);
  1083. dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
  1084. if (dai_data == NULL) {
  1085. pr_err("%s, dai_data is null\n", __func__);
  1086. ret = -EINVAL;
  1087. goto done;
  1088. }
  1089. dai_data->pcm_size = snd_pcm_lib_buffer_bytes(substream);
  1090. dai_data->pcm_count = snd_pcm_lib_period_bytes(substream);
  1091. dai_data->pcm_irq_pos = 0;
  1092. dai_data->pcm_buf_pos = 0;
  1093. dai_data->state = HPCM_PREPARED;
  1094. /* Register event notify processing callback in prepare instead of
  1095. * init() as q6voice module's init() can be called at a later point
  1096. */
  1097. voc_register_hpcm_evt_cb(hpcm_notify_evt_processing, &hpcm_drv);
  1098. tp = hpcm_get_tappoint_data(substream->pcm->id, prtd);
  1099. if (tp != NULL) {
  1100. ret = hpcm_start_vocpcm(substream->pcm->id, prtd, tp);
  1101. if (ret) {
  1102. pr_err("error sending start cmd err=%d\n", ret);
  1103. goto done;
  1104. }
  1105. } else {
  1106. pr_err("%s tp is NULL\n", __func__);
  1107. }
  1108. done:
  1109. mutex_unlock(&prtd->lock);
  1110. return ret;
  1111. }
  1112. static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
  1113. struct snd_pcm_hw_params *params)
  1114. {
  1115. struct snd_pcm_runtime *runtime = substream->runtime;
  1116. struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
  1117. struct hpcm_drv *prtd = (struct hpcm_drv *)runtime->private_data;
  1118. int ret = 0;
  1119. pr_debug("%s: %s\n", __func__, substream->pcm->id);
  1120. mutex_lock(&prtd->lock);
  1121. /* Allocate and map voice host PCM ion buffer */
  1122. if (prtd->session[prtd->mixer_conf.sess_indx].sess_paddr == 0) {
  1123. ret = hpcm_allocate_shared_memory(prtd);
  1124. if (ret) {
  1125. pr_err("error creating shared memory err=%d\n", ret);
  1126. goto done;
  1127. }
  1128. ret = hpcm_map_vocpcm_memory(prtd);
  1129. if (ret) {
  1130. pr_err("error mapping shared memory err=%d\n", ret);
  1131. hpcm_free_allocated_mem(prtd);
  1132. goto done;
  1133. }
  1134. } else {
  1135. pr_debug("%s, VHPCM memory allocation/mapping not performed\n"
  1136. , __func__);
  1137. }
  1138. dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
  1139. dma_buf->dev.dev = substream->pcm->card->dev;
  1140. dma_buf->private_data = NULL;
  1141. dma_buf->area = dma_alloc_coherent(substream->pcm->card->dev,
  1142. runtime->hw.buffer_bytes_max,
  1143. &dma_buf->addr, GFP_KERNEL);
  1144. if (!dma_buf->area) {
  1145. pr_err("%s:MSM dma_alloc failed\n", __func__);
  1146. ret = -ENOMEM;
  1147. goto done;
  1148. }
  1149. dma_buf->bytes = runtime->hw.buffer_bytes_max;
  1150. memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max);
  1151. hpcm_create_free_queue(dma_buf,
  1152. hpcm_get_dai_data(substream->pcm->id, prtd));
  1153. snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
  1154. done:
  1155. mutex_unlock(&prtd->lock);
  1156. return ret;
  1157. }
  1158. static int msm_pcm_open(struct snd_pcm_substream *substream)
  1159. {
  1160. struct snd_pcm_runtime *runtime = substream->runtime;
  1161. struct hpcm_drv *prtd = &hpcm_drv;
  1162. struct tappnt_mxr_data *tmd = NULL;
  1163. struct dai_data *dai_data = NULL;
  1164. int ret = 0;
  1165. int tp_val = 0;
  1166. pr_debug("%s, %s\n", __func__, substream->pcm->id);
  1167. mutex_lock(&prtd->lock);
  1168. dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
  1169. if (dai_data == NULL) {
  1170. pr_err("%s, dai_data is null\n", __func__);
  1171. ret = -EINVAL;
  1172. goto done;
  1173. }
  1174. runtime->hw = msm_pcm_hardware;
  1175. ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  1176. &constraints_sample_rates);
  1177. if (ret < 0)
  1178. pr_debug("snd_pcm_hw_constraint_list failed\n");
  1179. ret = snd_pcm_hw_constraint_integer(runtime,
  1180. SNDRV_PCM_HW_PARAM_PERIODS);
  1181. if (ret < 0) {
  1182. pr_debug("snd_pcm_hw_constraint_integer failed\n");
  1183. goto done;
  1184. }
  1185. tp_val = get_tappnt_value(substream->pcm->id);
  1186. tmd = hpcm_get_tappnt_mixer_data(substream->pcm->id, prtd);
  1187. /* Check wheather the kcontrol values set are valid */
  1188. if (!tmd ||
  1189. !(tmd->enable) ||
  1190. !hpcm_is_valid_config(prtd->mixer_conf.sess_indx,
  1191. tp_val, tmd->direction,
  1192. tmd->sample_rate)) {
  1193. ret = -EINVAL;
  1194. goto done;
  1195. }
  1196. dai_data->substream = substream;
  1197. runtime->private_data = prtd;
  1198. done:
  1199. mutex_unlock(&prtd->lock);
  1200. return ret;
  1201. }
  1202. static const struct snd_pcm_ops msm_pcm_ops = {
  1203. .open = msm_pcm_open,
  1204. .hw_params = msm_pcm_hw_params,
  1205. .prepare = msm_pcm_prepare,
  1206. .trigger = msm_pcm_trigger,
  1207. .pointer = msm_pcm_pointer,
  1208. .copy_user = msm_pcm_copy,
  1209. .close = msm_pcm_close,
  1210. };
  1211. static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
  1212. {
  1213. struct snd_card *card = rtd->card->snd_card;
  1214. pr_debug("%s:\n", __func__);
  1215. if (!card->dev->coherent_dma_mask)
  1216. card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  1217. return 0;
  1218. }
  1219. static int msm_pcm_hpcm_probe(struct snd_soc_platform *platform)
  1220. {
  1221. snd_soc_add_platform_controls(platform, msm_hpcm_controls,
  1222. ARRAY_SIZE(msm_hpcm_controls));
  1223. return 0;
  1224. }
  1225. static struct snd_soc_platform_driver msm_soc_platform = {
  1226. .ops = &msm_pcm_ops,
  1227. .pcm_new = msm_asoc_pcm_new,
  1228. .probe = msm_pcm_hpcm_probe,
  1229. };
  1230. static int msm_pcm_probe(struct platform_device *pdev)
  1231. {
  1232. pr_info("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
  1233. return snd_soc_register_platform(&pdev->dev, &msm_soc_platform);
  1234. }
  1235. static int msm_pcm_remove(struct platform_device *pdev)
  1236. {
  1237. snd_soc_unregister_platform(&pdev->dev);
  1238. return 0;
  1239. }
  1240. static const struct of_device_id msm_voice_host_pcm_dt_match[] = {
  1241. {.compatible = "qcom,msm-voice-host-pcm"},
  1242. {}
  1243. };
  1244. MODULE_DEVICE_TABLE(of, msm_voice_host_pcm_dt_match);
  1245. static struct platform_driver msm_pcm_driver = {
  1246. .driver = {
  1247. .name = "msm-voice-host-pcm",
  1248. .owner = THIS_MODULE,
  1249. .of_match_table = msm_voice_host_pcm_dt_match,
  1250. },
  1251. .probe = msm_pcm_probe,
  1252. .remove = msm_pcm_remove,
  1253. };
  1254. int __init msm_voice_host_init(void)
  1255. {
  1256. int i = 0;
  1257. struct session *s = NULL;
  1258. memset(&hpcm_drv, 0, sizeof(hpcm_drv));
  1259. mutex_init(&hpcm_drv.lock);
  1260. for (i = 0; i < MAX_SESSION; i++) {
  1261. s = &hpcm_drv.session[i];
  1262. spin_lock_init(&s->rx_tap_point.capture_dai_data.dsp_lock);
  1263. spin_lock_init(&s->rx_tap_point.playback_dai_data.dsp_lock);
  1264. spin_lock_init(&s->tx_tap_point.capture_dai_data.dsp_lock);
  1265. spin_lock_init(&s->tx_tap_point.playback_dai_data.dsp_lock);
  1266. init_waitqueue_head(
  1267. &s->rx_tap_point.capture_dai_data.queue_wait);
  1268. init_waitqueue_head(
  1269. &s->rx_tap_point.playback_dai_data.queue_wait);
  1270. init_waitqueue_head(
  1271. &s->tx_tap_point.capture_dai_data.queue_wait);
  1272. init_waitqueue_head(
  1273. &s->tx_tap_point.playback_dai_data.queue_wait);
  1274. INIT_LIST_HEAD(&s->rx_tap_point.capture_dai_data.filled_queue);
  1275. INIT_LIST_HEAD(&s->rx_tap_point.capture_dai_data.free_queue);
  1276. INIT_LIST_HEAD(&s->rx_tap_point.playback_dai_data.filled_queue);
  1277. INIT_LIST_HEAD(&s->rx_tap_point.playback_dai_data.free_queue);
  1278. INIT_LIST_HEAD(&s->tx_tap_point.capture_dai_data.filled_queue);
  1279. INIT_LIST_HEAD(&s->tx_tap_point.capture_dai_data.free_queue);
  1280. INIT_LIST_HEAD(&s->tx_tap_point.playback_dai_data.filled_queue);
  1281. INIT_LIST_HEAD(&s->tx_tap_point.playback_dai_data.free_queue);
  1282. }
  1283. return platform_driver_register(&msm_pcm_driver);
  1284. }
  1285. void msm_voice_host_exit(void)
  1286. {
  1287. platform_driver_unregister(&msm_pcm_driver);
  1288. }
  1289. MODULE_DESCRIPTION("PCM module platform driver");
  1290. MODULE_LICENSE("GPL v2");