msm-pcm-lpa-v2.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. /* Copyright (c) 2012-2017, 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/init.h>
  13. #include <linux/err.h>
  14. #include <linux/module.h>
  15. #include <linux/moduleparam.h>
  16. #include <linux/time.h>
  17. #include <linux/wait.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/slab.h>
  20. #include <sound/core.h>
  21. #include <sound/soc.h>
  22. #include <sound/soc-dapm.h>
  23. #include <sound/pcm.h>
  24. #include <sound/initval.h>
  25. #include <sound/control.h>
  26. #include <sound/pcm_params.h>
  27. #include <asm/dma.h>
  28. #include <linux/dma-mapping.h>
  29. #include <linux/of_device.h>
  30. #include <linux/msm_audio_ion.h>
  31. #include <sound/compress_params.h>
  32. #include <sound/compress_offload.h>
  33. #include <sound/compress_driver.h>
  34. #include <sound/timer.h>
  35. #include <sound/pcm_params.h>
  36. #include "msm-pcm-q6-v2.h"
  37. #include "msm-pcm-routing-v2.h"
  38. #include "audio_ocmem.h"
  39. #include <sound/pcm.h>
  40. #include <sound/tlv.h>
  41. #define LPA_LR_VOL_MAX_STEPS 0x20002000
  42. const DECLARE_TLV_DB_LINEAR(lpa_rx_vol_gain, 0,
  43. LPA_LR_VOL_MAX_STEPS);
  44. static struct audio_locks the_locks;
  45. struct snd_msm {
  46. atomic_t audio_ocmem_req;
  47. };
  48. static struct snd_msm lpa_audio;
  49. static struct snd_pcm_hardware msm_pcm_hardware = {
  50. .info = (SNDRV_PCM_INFO_MMAP |
  51. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  52. SNDRV_PCM_INFO_MMAP_VALID |
  53. SNDRV_PCM_INFO_INTERLEAVED |
  54. SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
  55. .formats = SNDRV_PCM_FMTBIT_S16_LE |
  56. SNDRV_PCM_FMTBIT_S24_LE,
  57. .rates = SNDRV_PCM_RATE_8000_192000 |
  58. SNDRV_PCM_RATE_KNOT,
  59. .rate_min = 8000,
  60. .rate_max = 192000,
  61. .channels_min = 1,
  62. .channels_max = 2,
  63. .buffer_bytes_max = 1024 * 1024,
  64. .period_bytes_min = 128 * 1024,
  65. .period_bytes_max = 256 * 1024,
  66. .periods_min = 4,
  67. .periods_max = 8,
  68. .fifo_size = 0,
  69. };
  70. /* Conventional and unconventional sample rate supported */
  71. static unsigned int supported_sample_rates[] = {
  72. 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
  73. 96000, 192000
  74. };
  75. static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
  76. .count = ARRAY_SIZE(supported_sample_rates),
  77. .list = supported_sample_rates,
  78. .mask = 0,
  79. };
  80. static void event_handler(uint32_t opcode,
  81. uint32_t token, uint32_t *payload, void *priv)
  82. {
  83. struct msm_audio *prtd = priv;
  84. struct snd_pcm_substream *substream = prtd->substream;
  85. struct snd_pcm_runtime *runtime = substream->runtime;
  86. struct audio_aio_write_param param;
  87. struct audio_buffer *buf = NULL;
  88. struct output_meta_data_st output_meta_data;
  89. unsigned long flag = 0;
  90. int i = 0;
  91. memset(&output_meta_data, 0x0, sizeof(struct output_meta_data_st));
  92. spin_lock_irqsave(&the_locks.event_lock, flag);
  93. switch (opcode) {
  94. case ASM_DATA_EVENT_WRITE_DONE_V2: {
  95. uint32_t *ptrmem = (uint32_t *)&param;
  96. pr_debug("ASM_DATA_EVENT_WRITE_DONE_V2\n");
  97. pr_debug("Buffer Consumed = 0x%08x\n", *ptrmem);
  98. prtd->pcm_irq_pos += prtd->pcm_count;
  99. if (atomic_read(&prtd->start))
  100. snd_pcm_period_elapsed(substream);
  101. else
  102. if (substream->timer_running)
  103. snd_timer_interrupt(substream->timer, 1);
  104. atomic_inc(&prtd->out_count);
  105. wake_up(&the_locks.write_wait);
  106. if (!atomic_read(&prtd->start)) {
  107. atomic_set(&prtd->pending_buffer, 1);
  108. break;
  109. } else
  110. atomic_set(&prtd->pending_buffer, 0);
  111. buf = prtd->audio_client->port[IN].buf;
  112. if (runtime->status->hw_ptr >= runtime->control->appl_ptr) {
  113. runtime->render_flag |= SNDRV_RENDER_STOPPED;
  114. pr_info("%s:lpa driver underrun\n", __func__);
  115. break;
  116. }
  117. pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
  118. __func__, prtd->pcm_count, prtd->out_head);
  119. pr_debug("%s:writing buffer[%d] from 0x%08x\n",
  120. __func__, prtd->out_head,
  121. ((unsigned int)buf[0].phys +
  122. (prtd->out_head * prtd->pcm_count)));
  123. if (prtd->meta_data_mode) {
  124. memcpy(&output_meta_data, (char *)(buf->data +
  125. prtd->out_head * prtd->pcm_count),
  126. sizeof(struct output_meta_data_st));
  127. param.len = output_meta_data.frame_size;
  128. } else {
  129. param.len = prtd->pcm_count;
  130. }
  131. pr_debug("meta_data_length: %d, frame_length: %d\n",
  132. output_meta_data.meta_data_length,
  133. output_meta_data.frame_size);
  134. param.paddr = (unsigned long)buf[0].phys +
  135. (prtd->out_head * prtd->pcm_count) +
  136. output_meta_data.meta_data_length;
  137. param.msw_ts = output_meta_data.timestamp_msw;
  138. param.lsw_ts = output_meta_data.timestamp_lsw;
  139. param.flags = NO_TIMESTAMP;
  140. param.uid = ((unsigned long)buf[0].phys
  141. + (prtd->out_head * prtd->pcm_count)
  142. + output_meta_data.meta_data_length);
  143. for (i = 0; i < sizeof(struct audio_aio_write_param)/4;
  144. i++, ++ptrmem)
  145. pr_debug("cmd[%d]=0x%08x\n", i, *ptrmem);
  146. if (q6asm_async_write(prtd->audio_client,
  147. &param) < 0)
  148. pr_err("%s:q6asm_async_write failed\n",
  149. __func__);
  150. else
  151. prtd->out_head =
  152. (prtd->out_head + 1) & (runtime->periods - 1);
  153. atomic_set(&prtd->pending_buffer, 0);
  154. break;
  155. }
  156. case ASM_DATA_EVENT_RENDERED_EOS:
  157. pr_debug("ASM_DATA_CMDRSP_EOS\n");
  158. prtd->cmd_ack = 1;
  159. wake_up(&the_locks.eos_wait);
  160. break;
  161. case APR_BASIC_RSP_RESULT: {
  162. switch (payload[0]) {
  163. case ASM_SESSION_CMD_RUN_V2: {
  164. if (!atomic_read(&prtd->pending_buffer))
  165. break;
  166. pr_debug("%s:writing %d bytes of buffer to dsp\n",
  167. __func__, prtd->pcm_count);
  168. buf = prtd->audio_client->port[IN].buf;
  169. pr_debug("%s:writing buffer[%d] from 0x%08x\n",
  170. __func__, prtd->out_head,
  171. ((unsigned int)buf[0].phys +
  172. (prtd->out_head * prtd->pcm_count)));
  173. if (prtd->meta_data_mode) {
  174. memcpy(&output_meta_data, (char *)(buf->data +
  175. prtd->out_head * prtd->pcm_count),
  176. sizeof(struct output_meta_data_st));
  177. param.len = output_meta_data.frame_size;
  178. } else {
  179. param.len = prtd->pcm_count;
  180. }
  181. param.paddr = (unsigned long)buf[prtd->out_head].phys +
  182. output_meta_data.meta_data_length;
  183. param.msw_ts = output_meta_data.timestamp_msw;
  184. param.lsw_ts = output_meta_data.timestamp_lsw;
  185. param.flags = NO_TIMESTAMP;
  186. param.uid = (unsigned long)buf[prtd->out_head].phys +
  187. output_meta_data.meta_data_length;
  188. if (q6asm_async_write(prtd->audio_client,
  189. &param) < 0)
  190. pr_err("%s:q6asm_async_write failed\n",
  191. __func__);
  192. else
  193. prtd->out_head =
  194. (prtd->out_head + 1)
  195. & (runtime->periods - 1);
  196. atomic_set(&prtd->pending_buffer, 0);
  197. }
  198. break;
  199. case ASM_STREAM_CMD_FLUSH:
  200. pr_debug("ASM_STREAM_CMD_FLUSH\n");
  201. prtd->cmd_ack = 1;
  202. wake_up(&the_locks.eos_wait);
  203. break;
  204. default:
  205. break;
  206. }
  207. break;
  208. }
  209. default:
  210. pr_debug("Not Supported Event opcode[0x%x]\n", opcode);
  211. break;
  212. }
  213. spin_unlock_irqrestore(&the_locks.event_lock, flag);
  214. }
  215. static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
  216. {
  217. struct snd_pcm_runtime *runtime = substream->runtime;
  218. struct msm_audio *prtd = runtime->private_data;
  219. int ret;
  220. uint16_t bits_per_sample = 16;
  221. u32 io_mode = ASYNC_IO_MODE;
  222. pr_debug("%s\n", __func__);
  223. prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
  224. prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
  225. prtd->pcm_irq_pos = 0;
  226. /* rate and channels are sent to audio driver */
  227. prtd->samp_rate = runtime->rate;
  228. prtd->channel_mode = runtime->channels;
  229. prtd->out_head = 0;
  230. if (prtd->enabled)
  231. return 0;
  232. switch (runtime->format) {
  233. case SNDRV_PCM_FORMAT_S16_LE:
  234. bits_per_sample = 16;
  235. break;
  236. case SNDRV_PCM_FORMAT_S24_LE:
  237. bits_per_sample = 24;
  238. break;
  239. }
  240. if (prtd->meta_data_mode)
  241. io_mode |= COMPRESSED_IO;
  242. ret = q6asm_set_io_mode(prtd->audio_client, io_mode);
  243. if (ret < 0) {
  244. pr_err("%s: Set IO mode failed\n", __func__);
  245. q6asm_audio_client_free(prtd->audio_client);
  246. prtd->audio_client = NULL;
  247. return -ENOMEM;
  248. }
  249. ret = q6asm_media_format_block_pcm_format_support(
  250. prtd->audio_client, runtime->rate,
  251. runtime->channels, bits_per_sample);
  252. if (ret < 0)
  253. pr_debug("%s: CMD Format block failed\n", __func__);
  254. atomic_set(&prtd->out_count, runtime->periods);
  255. prtd->enabled = 1;
  256. prtd->cmd_ack = 0;
  257. prtd->cmd_interrupt = 0;
  258. return 0;
  259. }
  260. static int msm_pcm_restart(struct snd_pcm_substream *substream)
  261. {
  262. struct snd_pcm_runtime *runtime = substream->runtime;
  263. struct msm_audio *prtd = runtime->private_data;
  264. struct audio_aio_write_param param;
  265. struct audio_buffer *buf = NULL;
  266. struct output_meta_data_st output_meta_data;
  267. pr_debug("%s: restart\n", __func__);
  268. memset(&output_meta_data, 0x0, sizeof(struct output_meta_data_st));
  269. if (runtime->render_flag & SNDRV_RENDER_STOPPED) {
  270. buf = prtd->audio_client->port[IN].buf;
  271. pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
  272. __func__, prtd->pcm_count, prtd->out_head);
  273. pr_debug("%s:writing buffer[%d] from 0x%08x\n",
  274. __func__, prtd->out_head,
  275. ((unsigned int)buf[0].phys +
  276. (prtd->out_head * prtd->pcm_count)));
  277. if (prtd->meta_data_mode) {
  278. memcpy(&output_meta_data, (char *)(buf->data +
  279. prtd->out_head * prtd->pcm_count),
  280. sizeof(struct output_meta_data_st));
  281. param.len = output_meta_data.frame_size;
  282. } else {
  283. param.len = prtd->pcm_count;
  284. }
  285. pr_debug("meta_data_length: %d, frame_length: %d\n",
  286. output_meta_data.meta_data_length,
  287. output_meta_data.frame_size);
  288. pr_debug("timestamp_msw: %d, timestamp_lsw: %d\n",
  289. output_meta_data.timestamp_msw,
  290. output_meta_data.timestamp_lsw);
  291. param.paddr = ((unsigned long)buf[0].phys +
  292. (prtd->out_head * prtd->pcm_count) +
  293. output_meta_data.meta_data_length);
  294. param.msw_ts = output_meta_data.timestamp_msw;
  295. param.lsw_ts = output_meta_data.timestamp_lsw;
  296. param.flags = NO_TIMESTAMP;
  297. param.uid = ((unsigned long)buf[0].phys +
  298. (prtd->out_head * prtd->pcm_count) +
  299. output_meta_data.meta_data_length);
  300. if (q6asm_async_write(prtd->audio_client, &param) < 0)
  301. pr_err("%s:q6asm_async_write failed\n",
  302. __func__);
  303. else
  304. prtd->out_head =
  305. (prtd->out_head + 1) & (runtime->periods - 1);
  306. runtime->render_flag &= ~SNDRV_RENDER_STOPPED;
  307. return 0;
  308. }
  309. return 0;
  310. }
  311. static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
  312. {
  313. int ret = 0;
  314. struct snd_pcm_runtime *runtime = substream->runtime;
  315. struct msm_audio *prtd = runtime->private_data;
  316. pr_debug("%s\n", __func__);
  317. switch (cmd) {
  318. case SNDRV_PCM_TRIGGER_START:
  319. prtd->pcm_irq_pos = 0;
  320. atomic_set(&prtd->pending_buffer, 1);
  321. case SNDRV_PCM_TRIGGER_RESUME:
  322. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  323. pr_debug("SNDRV_PCM_TRIGGER_START\n");
  324. q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
  325. atomic_set(&prtd->start, 1);
  326. atomic_set(&prtd->stop, 0);
  327. break;
  328. case SNDRV_PCM_TRIGGER_STOP:
  329. pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
  330. atomic_set(&prtd->start, 0);
  331. atomic_set(&prtd->stop, 1);
  332. runtime->render_flag &= ~SNDRV_RENDER_STOPPED;
  333. if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
  334. break;
  335. break;
  336. case SNDRV_PCM_TRIGGER_SUSPEND:
  337. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  338. pr_debug("SNDRV_PCM_TRIGGER_PAUSE\n");
  339. q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
  340. atomic_set(&prtd->start, 0);
  341. runtime->render_flag &= ~SNDRV_RENDER_STOPPED;
  342. break;
  343. default:
  344. ret = -EINVAL;
  345. break;
  346. }
  347. return ret;
  348. }
  349. static int msm_pcm_open(struct snd_pcm_substream *substream)
  350. {
  351. struct snd_pcm_runtime *runtime = substream->runtime;
  352. struct msm_audio *prtd;
  353. int ret = 0;
  354. pr_debug("%s\n", __func__);
  355. prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL);
  356. if (prtd == NULL) {
  357. pr_err("Failed to allocate memory for msm_audio\n");
  358. return -ENOMEM;
  359. }
  360. runtime->hw = msm_pcm_hardware;
  361. prtd->substream = substream;
  362. runtime->render_flag = SNDRV_DMA_MODE;
  363. prtd->audio_client = q6asm_audio_client_alloc(
  364. (app_cb)event_handler, prtd);
  365. if (!prtd->audio_client) {
  366. pr_debug("%s: Could not allocate memory\n", __func__);
  367. kfree(prtd);
  368. return -ENOMEM;
  369. }
  370. prtd->meta_data_mode = false;
  371. /* Capture path */
  372. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  373. return -EPERM;
  374. ret = snd_pcm_hw_constraint_list(runtime, 0,
  375. SNDRV_PCM_HW_PARAM_RATE,
  376. &constraints_sample_rates);
  377. if (ret < 0)
  378. pr_debug("snd_pcm_hw_constraint_list failed\n");
  379. /* Ensure that buffer size is a multiple of period size */
  380. ret = snd_pcm_hw_constraint_integer(runtime,
  381. SNDRV_PCM_HW_PARAM_PERIODS);
  382. if (ret < 0)
  383. pr_debug("snd_pcm_hw_constraint_integer failed\n");
  384. prtd->dsp_cnt = 0;
  385. atomic_set(&prtd->pending_buffer, 1);
  386. atomic_set(&prtd->stop, 1);
  387. atomic_set(&lpa_audio.audio_ocmem_req, 0);
  388. runtime->private_data = prtd;
  389. if (!atomic_cmpxchg(&lpa_audio.audio_ocmem_req, 0, 1))
  390. audio_ocmem_process_req(AUDIO, true);
  391. else
  392. atomic_inc(&lpa_audio.audio_ocmem_req);
  393. pr_debug("%s: req: %d\n", __func__,
  394. atomic_read(&lpa_audio.audio_ocmem_req));
  395. return 0;
  396. }
  397. static int lpa_set_volume(struct msm_audio *prtd, uint32_t volume)
  398. {
  399. int rc = 0;
  400. if (prtd && prtd->audio_client) {
  401. rc = q6asm_set_lrgain(prtd->audio_client,
  402. (volume >> 16) & 0xFFFF, volume & 0xFFFF);
  403. if (rc < 0) {
  404. pr_err("%s: Send Volume command failed rc=%d\n",
  405. __func__, rc);
  406. } else {
  407. prtd->volume = volume;
  408. }
  409. }
  410. return rc;
  411. }
  412. static int msm_pcm_playback_close(struct snd_pcm_substream *substream)
  413. {
  414. struct snd_pcm_runtime *runtime = substream->runtime;
  415. struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
  416. struct msm_audio *prtd = runtime->private_data;
  417. int dir = 0;
  418. int rc = 0;
  419. /*
  420. If routing is still enabled, we need to issue EOS to
  421. the DSP
  422. To issue EOS to dsp, we need to be run state otherwise
  423. EOS is not honored.
  424. */
  425. if (msm_routing_check_backend_enabled(soc_prtd->dai_link->be_id) &&
  426. (!atomic_read(&prtd->stop))) {
  427. rc = q6asm_run(prtd->audio_client, 0, 0, 0);
  428. atomic_set(&prtd->pending_buffer, 0);
  429. prtd->cmd_ack = 0;
  430. q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
  431. pr_debug("%s\n", __func__);
  432. rc = wait_event_timeout(the_locks.eos_wait,
  433. prtd->cmd_ack, 5 * HZ);
  434. if (!rc)
  435. pr_err("EOS cmd timeout\n");
  436. prtd->pcm_irq_pos = 0;
  437. }
  438. if (prtd->audio_client) {
  439. dir = IN;
  440. atomic_set(&prtd->pending_buffer, 0);
  441. if (atomic_read(&lpa_audio.audio_ocmem_req) > 1)
  442. atomic_dec(&lpa_audio.audio_ocmem_req);
  443. else if (atomic_cmpxchg(&lpa_audio.audio_ocmem_req, 1, 0))
  444. audio_ocmem_process_req(AUDIO, false);
  445. pr_debug("%s: req: %d\n", __func__,
  446. atomic_read(&lpa_audio.audio_ocmem_req));
  447. q6asm_cmd(prtd->audio_client, CMD_CLOSE);
  448. q6asm_audio_client_buf_free_contiguous(dir,
  449. prtd->audio_client);
  450. atomic_set(&prtd->stop, 1);
  451. q6asm_audio_client_free(prtd->audio_client);
  452. pr_debug("%s\n", __func__);
  453. }
  454. msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
  455. SNDRV_PCM_STREAM_PLAYBACK);
  456. prtd->meta_data_mode = false;
  457. pr_debug("%s\n", __func__);
  458. kfree(prtd);
  459. runtime->private_data = NULL;
  460. return 0;
  461. }
  462. static int msm_pcm_close(struct snd_pcm_substream *substream)
  463. {
  464. int ret = 0;
  465. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  466. ret = msm_pcm_playback_close(substream);
  467. return ret;
  468. }
  469. static int msm_pcm_prepare(struct snd_pcm_substream *substream)
  470. {
  471. int ret = 0;
  472. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  473. ret = msm_pcm_playback_prepare(substream);
  474. return ret;
  475. }
  476. static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
  477. {
  478. struct snd_pcm_runtime *runtime = substream->runtime;
  479. struct msm_audio *prtd = runtime->private_data;
  480. if (prtd->pcm_irq_pos >= prtd->pcm_size)
  481. prtd->pcm_irq_pos = 0;
  482. pr_debug("%s: pcm_irq_pos = %d\n", __func__, prtd->pcm_irq_pos);
  483. return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
  484. }
  485. static int msm_pcm_mmap(struct snd_pcm_substream *substream,
  486. struct vm_area_struct *vma)
  487. {
  488. struct snd_pcm_runtime *runtime = substream->runtime;
  489. struct msm_audio *prtd = runtime->private_data;
  490. struct audio_client *ac = prtd->audio_client;
  491. struct audio_port_data *apd = ac->port;
  492. struct audio_buffer *ab;
  493. int dir = -1;
  494. prtd->mmap_flag = 1;
  495. runtime->render_flag = SNDRV_NON_DMA_MODE;
  496. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  497. dir = IN;
  498. else
  499. dir = OUT;
  500. ab = &(apd[dir].buf[0]);
  501. return msm_audio_ion_mmap(ab, vma);
  502. }
  503. static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
  504. struct snd_pcm_hw_params *params)
  505. {
  506. struct snd_pcm_runtime *runtime = substream->runtime;
  507. struct msm_audio *prtd = runtime->private_data;
  508. struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
  509. struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
  510. struct audio_buffer *buf;
  511. uint16_t bits_per_sample = 16;
  512. int dir, ret;
  513. struct asm_softpause_params softpause = {
  514. .enable = SOFT_PAUSE_ENABLE,
  515. .period = SOFT_PAUSE_PERIOD,
  516. .step = SOFT_PAUSE_STEP,
  517. .rampingcurve = SOFT_PAUSE_CURVE_LINEAR,
  518. };
  519. struct asm_softvolume_params softvol = {
  520. .period = SOFT_VOLUME_PERIOD,
  521. .step = SOFT_VOLUME_STEP,
  522. .rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
  523. };
  524. prtd->audio_client->perf_mode = false;
  525. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  526. if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE)
  527. bits_per_sample = 24;
  528. ret = q6asm_open_write_v2(prtd->audio_client,
  529. FORMAT_LINEAR_PCM, bits_per_sample);
  530. if (ret < 0) {
  531. pr_err("%s: pcm out open failed\n", __func__);
  532. q6asm_audio_client_free(prtd->audio_client);
  533. prtd->audio_client = NULL;
  534. return -ENOMEM;
  535. }
  536. }
  537. pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session);
  538. prtd->session_id = prtd->audio_client->session;
  539. msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
  540. prtd->audio_client->perf_mode,
  541. prtd->session_id, substream->stream);
  542. lpa_set_volume(prtd, 0);
  543. ret = q6asm_set_softpause(prtd->audio_client, &softpause);
  544. if (ret < 0)
  545. pr_err("%s: Send SoftPause Param failed ret=%d\n",
  546. __func__, ret);
  547. ret = q6asm_set_softvolume(prtd->audio_client, &softvol);
  548. if (ret < 0)
  549. pr_err("%s: Send SoftVolume Param failed ret=%d\n",
  550. __func__, ret);
  551. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  552. dir = IN;
  553. else
  554. return -EPERM;
  555. ret = q6asm_audio_client_buf_alloc_contiguous(dir,
  556. prtd->audio_client,
  557. params_period_bytes(params),
  558. params_periods(params));
  559. if (ret < 0) {
  560. pr_err("Audio Start: Buffer Allocation failed rc = %d\n",
  561. ret);
  562. return -ENOMEM;
  563. }
  564. buf = prtd->audio_client->port[dir].buf;
  565. if (buf == NULL || buf[0].data == NULL)
  566. return -ENOMEM;
  567. pr_debug("%s:buf = %p\n", __func__, buf);
  568. dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
  569. dma_buf->dev.dev = substream->pcm->card->dev;
  570. dma_buf->private_data = NULL;
  571. dma_buf->area = buf[0].data;
  572. dma_buf->addr = buf[0].phys;
  573. dma_buf->bytes = params_period_bytes(params) * params_periods(params);
  574. if (!dma_buf->area)
  575. return -ENOMEM;
  576. snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
  577. return 0;
  578. }
  579. static int msm_pcm_ioctl(struct snd_pcm_substream *substream,
  580. unsigned int cmd, void *arg)
  581. {
  582. int rc = 0;
  583. struct snd_pcm_runtime *runtime = substream->runtime;
  584. struct msm_audio *prtd = runtime->private_data;
  585. uint64_t timestamp;
  586. uint64_t temp;
  587. switch (cmd) {
  588. case SNDRV_COMPRESS_TSTAMP: {
  589. struct snd_compr_tstamp tstamp;
  590. pr_debug("SNDRV_COMPRESS_TSTAMP\n");
  591. memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
  592. rc = q6asm_get_session_time(prtd->audio_client, &timestamp);
  593. if (rc < 0) {
  594. pr_err("%s: Fail to get session time stamp, rc:%d\n",
  595. __func__, rc);
  596. return -EAGAIN;
  597. }
  598. temp = (timestamp * 2 * runtime->channels);
  599. temp = temp * (runtime->rate/1000);
  600. temp = div_u64(temp, 1000);
  601. tstamp.sampling_rate = runtime->rate;
  602. tstamp.timestamp = timestamp;
  603. pr_debug("%s: bytes_consumed:timestamp = %lld,\n",
  604. __func__,
  605. tstamp.timestamp);
  606. if (copy_to_user((void *) arg, &tstamp,
  607. sizeof(struct snd_compr_tstamp)))
  608. return -EFAULT;
  609. return 0;
  610. }
  611. case SNDRV_PCM_IOCTL1_RESET:
  612. prtd->cmd_ack = 0;
  613. rc = q6asm_cmd(prtd->audio_client, CMD_FLUSH);
  614. if (rc < 0)
  615. pr_err("%s: flush cmd failed rc=%d\n", __func__, rc);
  616. rc = wait_event_timeout(the_locks.eos_wait,
  617. prtd->cmd_ack, 5 * HZ);
  618. if (!rc)
  619. pr_err("Flush cmd timeout\n");
  620. prtd->pcm_irq_pos = 0;
  621. break;
  622. case SNDRV_COMPRESS_METADATA_MODE:
  623. if (!atomic_read(&prtd->start)) {
  624. pr_debug("Metadata mode enabled\n");
  625. prtd->meta_data_mode = true;
  626. return 0;
  627. }
  628. pr_debug("Metadata mode not enabled\n");
  629. return -EPERM;
  630. default:
  631. break;
  632. }
  633. return snd_pcm_lib_ioctl(substream, cmd, arg);
  634. }
  635. static int msm_lpa_volume_ctl_put(struct snd_kcontrol *kcontrol,
  636. struct snd_ctl_elem_value *ucontrol)
  637. {
  638. int rc = 0;
  639. struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol);
  640. struct snd_pcm_substream *substream =
  641. vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
  642. struct msm_audio *prtd;
  643. int volume = ucontrol->value.integer.value[0];
  644. pr_debug("%s: volume : %x\n", __func__, volume);
  645. if (!substream)
  646. return -ENODEV;
  647. if (!substream->runtime)
  648. return 0;
  649. prtd = substream->runtime->private_data;
  650. if (prtd)
  651. rc = lpa_set_volume(prtd, volume);
  652. return rc;
  653. }
  654. static int msm_lpa_volume_ctl_get(struct snd_kcontrol *kcontrol,
  655. struct snd_ctl_elem_value *ucontrol)
  656. {
  657. struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol);
  658. struct snd_pcm_substream *substream =
  659. vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
  660. struct msm_audio *prtd;
  661. pr_debug("%s\n", __func__);
  662. if (!substream)
  663. return -ENODEV;
  664. if (!substream->runtime)
  665. return 0;
  666. prtd = substream->runtime->private_data;
  667. if (prtd)
  668. ucontrol->value.integer.value[0] = prtd->volume;
  669. return 0;
  670. }
  671. static int msm_lpa_add_controls(struct snd_soc_pcm_runtime *rtd)
  672. {
  673. int ret = 0;
  674. struct snd_pcm *pcm = rtd->pcm->streams[0].pcm;
  675. struct snd_pcm_volume *volume_info;
  676. struct snd_kcontrol *kctl;
  677. dev_dbg(rtd->dev, "%s, Volume cntrl add\n", __func__);
  678. ret = snd_pcm_add_volume_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  679. NULL, 1, rtd->dai_link->be_id,
  680. &volume_info);
  681. if (ret < 0)
  682. return ret;
  683. kctl = volume_info->kctl;
  684. kctl->put = msm_lpa_volume_ctl_put;
  685. kctl->get = msm_lpa_volume_ctl_get;
  686. kctl->tlv.p = lpa_rx_vol_gain;
  687. return 0;
  688. }
  689. static struct snd_pcm_ops msm_pcm_ops = {
  690. .open = msm_pcm_open,
  691. .hw_params = msm_pcm_hw_params,
  692. .close = msm_pcm_close,
  693. .ioctl = msm_pcm_ioctl,
  694. .prepare = msm_pcm_prepare,
  695. .trigger = msm_pcm_trigger,
  696. .pointer = msm_pcm_pointer,
  697. .mmap = msm_pcm_mmap,
  698. .restart = msm_pcm_restart,
  699. };
  700. static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
  701. {
  702. struct snd_card *card = rtd->card->snd_card;
  703. int ret = 0;
  704. if (!card->dev->coherent_dma_mask)
  705. card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  706. ret = msm_lpa_add_controls(rtd);
  707. if (ret)
  708. pr_err("%s, kctl add failed\n", __func__);
  709. return ret;
  710. }
  711. static struct snd_soc_platform_driver msm_soc_platform = {
  712. .ops = &msm_pcm_ops,
  713. .pcm_new = msm_asoc_pcm_new,
  714. };
  715. static __devinit int msm_pcm_probe(struct platform_device *pdev)
  716. {
  717. if (pdev->dev.of_node)
  718. dev_set_name(&pdev->dev, "%s", "msm-pcm-lpa");
  719. dev_info(&pdev->dev, "%s: dev name %s\n",
  720. __func__, dev_name(&pdev->dev));
  721. atomic_set(&lpa_audio.audio_ocmem_req, 0);
  722. return snd_soc_register_platform(&pdev->dev,
  723. &msm_soc_platform);
  724. }
  725. static int msm_pcm_remove(struct platform_device *pdev)
  726. {
  727. snd_soc_unregister_platform(&pdev->dev);
  728. return 0;
  729. }
  730. static const struct of_device_id msm_pcm_lpa_dt_match[] = {
  731. {.compatible = "qcom,msm-pcm-lpa"},
  732. {}
  733. };
  734. MODULE_DEVICE_TABLE(of, msm_pcm_lpa_dt_match);
  735. static struct platform_driver msm_pcm_driver = {
  736. .driver = {
  737. .name = "msm-pcm-lpa",
  738. .owner = THIS_MODULE,
  739. .of_match_table = msm_pcm_lpa_dt_match,
  740. },
  741. .probe = msm_pcm_probe,
  742. .remove = __devexit_p(msm_pcm_remove),
  743. };
  744. static int __init msm_soc_platform_init(void)
  745. {
  746. spin_lock_init(&the_locks.event_lock);
  747. init_waitqueue_head(&the_locks.enable_wait);
  748. init_waitqueue_head(&the_locks.eos_wait);
  749. init_waitqueue_head(&the_locks.write_wait);
  750. init_waitqueue_head(&the_locks.read_wait);
  751. return platform_driver_register(&msm_pcm_driver);
  752. }
  753. module_init(msm_soc_platform_init);
  754. static void __exit msm_soc_platform_exit(void)
  755. {
  756. platform_driver_unregister(&msm_pcm_driver);
  757. }
  758. module_exit(msm_soc_platform_exit);
  759. MODULE_DESCRIPTION("PCM module platform driver");
  760. MODULE_LICENSE("GPL v2");