msm-mvs.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. /* Copyright (c) 2010, The Linux Foundation. All rights reserved.
  2. *
  3. * All source code in this file is licensed under the following license except
  4. * where indicated.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License version 2 as published
  8. * by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU General Public License for more details.
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, you can find it at http://www.fsf.org.
  17. */
  18. #include <linux/init.h>
  19. #include <linux/err.h>
  20. #include <linux/module.h>
  21. #include <linux/moduleparam.h>
  22. #include <linux/time.h>
  23. #include <linux/wait.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/mutex.h>
  26. #include <sound/core.h>
  27. #include <sound/soc.h>
  28. #include <sound/pcm.h>
  29. #include <sound/initval.h>
  30. #include <sound/control.h>
  31. #include <linux/kthread.h>
  32. #include <linux/uaccess.h>
  33. #include <linux/mutex.h>
  34. #include <linux/wakelock.h>
  35. #include <mach/msm_rpcrouter.h>
  36. #include <mach/debug_mm.h>
  37. #include "msm_audio_mvs.h"
  38. static struct audio_mvs_info_type audio_mvs_info;
  39. static struct snd_pcm_hardware msm_pcm_hardware = {
  40. .info = SNDRV_PCM_INFO_INTERLEAVED,
  41. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  42. .rates = (SNDRV_PCM_RATE_8000),
  43. .rate_min = 8000,
  44. .rate_max = 8000,
  45. .channels_min = 1,
  46. .channels_max = 2,
  47. .buffer_bytes_max = MVS_MAX_VOC_PKT_SIZE * MVS_MAX_Q_LEN,
  48. .period_bytes_min = MVS_MAX_VOC_PKT_SIZE,
  49. .period_bytes_max = MVS_MAX_VOC_PKT_SIZE,
  50. .periods_min = MVS_MAX_Q_LEN,
  51. .periods_max = MVS_MAX_Q_LEN,
  52. .fifo_size = 0,
  53. };
  54. static void snd_pcm_mvs_timer(unsigned long data)
  55. {
  56. struct audio_mvs_info_type *audio = &audio_mvs_info;
  57. MM_DBG("%s\n", __func__);
  58. if (audio->playback_start) {
  59. if (audio->ack_dl_count) {
  60. audio->pcm_playback_irq_pos += audio->pcm_count;
  61. audio->ack_dl_count--;
  62. snd_pcm_period_elapsed(audio->playback_substream);
  63. }
  64. }
  65. if (audio->capture_start) {
  66. if (audio->ack_ul_count) {
  67. audio->pcm_capture_irq_pos += audio->pcm_capture_count;
  68. audio->ack_ul_count--;
  69. snd_pcm_period_elapsed(audio->capture_substream);
  70. }
  71. }
  72. audio->timer.expires += audio->expiry_delta;
  73. add_timer(&audio->timer);
  74. }
  75. static int audio_mvs_setup_mvs(struct audio_mvs_info_type *audio)
  76. {
  77. int rc = 0;
  78. struct audio_mvs_enable_msg enable_msg;
  79. MM_DBG("%s\n", __func__);
  80. /* Enable MVS. */
  81. memset(&enable_msg, 0, sizeof(enable_msg));
  82. audio->rpc_status = RPC_STATUS_FAILURE;
  83. enable_msg.enable_args.client_id = cpu_to_be32(MVS_CLIENT_ID_VOIP);
  84. enable_msg.enable_args.mode = cpu_to_be32(MVS_MODE_LINEAR_PCM);
  85. enable_msg.enable_args.ul_cb_func_id = (int) NULL;
  86. enable_msg.enable_args.dl_cb_func_id = (int) NULL;
  87. enable_msg.enable_args.context = cpu_to_be32(MVS_PKT_CONTEXT_ISR);
  88. msm_rpc_setup_req(&enable_msg.rpc_hdr, MVS_PROG,
  89. MVS_VERS, MVS_ENABLE_PROC);
  90. rc = msm_rpc_write(audio->rpc_endpt,
  91. &enable_msg, sizeof(enable_msg));
  92. if (rc >= 0) {
  93. MM_DBG("RPC write for enable done\n");
  94. rc = wait_event_timeout(audio->wait,
  95. (audio->rpc_status !=
  96. RPC_STATUS_FAILURE), 1 * HZ);
  97. if (rc > 0) {
  98. MM_DBG("Wait event for enable succeeded\n");
  99. mutex_lock(&audio->lock);
  100. audio->mvs_mode = MVS_MODE_LINEAR_PCM;
  101. audio->frame_mode = MVS_FRAME_MODE_PCM_DL;
  102. audio->pcm_frame = 0;
  103. mutex_unlock(&audio->lock);
  104. rc = 0;
  105. } else
  106. MM_ERR("Wait event for enable failed %d\n", rc);
  107. } else
  108. MM_ERR("RPC write for enable failed %d\n", rc);
  109. return rc;
  110. }
  111. static void audio_mvs_rpc_reply(struct msm_rpc_endpoint *endpoint,
  112. uint32_t xid)
  113. {
  114. int rc = 0;
  115. struct rpc_reply_hdr reply_hdr;
  116. MM_DBG("%s\n", __func__);
  117. memset(&reply_hdr, 0, sizeof(reply_hdr));
  118. reply_hdr.xid = cpu_to_be32(xid);
  119. reply_hdr.type = cpu_to_be32(RPC_TYPE_REPLY);
  120. reply_hdr.reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
  121. reply_hdr.data.acc_hdr.accept_stat =
  122. cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS);
  123. reply_hdr.data.acc_hdr.verf_flavor = 0;
  124. reply_hdr.data.acc_hdr.verf_length = 0;
  125. rc = msm_rpc_write(endpoint, &reply_hdr, sizeof(reply_hdr));
  126. if (rc < 0)
  127. MM_ERR("RPC write for response failed %d\n", rc);
  128. }
  129. static void audio_mvs_process_rpc_request(uint32_t procedure, uint32_t xid,
  130. void *data, uint32_t length,
  131. struct audio_mvs_info_type *audio)
  132. {
  133. int rc = 0;
  134. uint32_t index;
  135. MM_DBG("%s\n", __func__);
  136. switch (procedure) {
  137. case MVS_EVENT_CB_TYPE_PROC:{
  138. struct audio_mvs_cb_func_args *args = data;
  139. uint32_t event_type = be32_to_cpu(args->event);
  140. uint32_t cmd_status =
  141. be32_to_cpu(args->
  142. event_data.mvs_ev_command_type.cmd_status);
  143. uint32_t mode_status =
  144. be32_to_cpu(args->
  145. event_data.mvs_ev_mode_type.mode_status);
  146. audio_mvs_rpc_reply(audio->rpc_endpt, xid);
  147. if (be32_to_cpu(args->valid_ptr)) {
  148. if (event_type == AUDIO_MVS_COMMAND) {
  149. if (cmd_status == AUDIO_MVS_CMD_SUCCESS)
  150. audio->rpc_status = RPC_STATUS_SUCCESS;
  151. wake_up(&audio->wait);
  152. } else if (event_type == AUDIO_MVS_MODE) {
  153. if (mode_status != AUDIO_MVS_MODE_NOT_AVAIL) {
  154. audio->rpc_status =
  155. RPC_STATUS_SUCCESS;
  156. }
  157. audio->prepare_ack++;
  158. wake_up(&audio->wait);
  159. wake_up(&audio->prepare_wait);
  160. } else {
  161. /*nothing to do */
  162. }
  163. } else
  164. MM_ERR("ALSA: CB event pointer not valid\n");
  165. break;
  166. }
  167. case MVS_PACKET_UL_FN_TYPE_PROC:{
  168. uint32_t *cb_data = data;
  169. uint32_t pkt_len ;
  170. struct audio_mvs_ul_reply ul_reply;
  171. MM_DBG("MVS_PACKET_UL_FN_TYPE_PROC\n");
  172. memset(&ul_reply, 0, sizeof(ul_reply));
  173. cb_data++;
  174. pkt_len = be32_to_cpu(*cb_data);
  175. cb_data++;
  176. if (audio->capture_enable) {
  177. audio_mvs_info.ack_ul_count++;
  178. mutex_lock(&audio->out_lock);
  179. index = audio->out_write % MVS_MAX_Q_LEN;
  180. memcpy(audio->out[index].voc_pkt, cb_data,
  181. pkt_len);
  182. audio->out[index].len = pkt_len;
  183. audio->out_write++;
  184. mutex_unlock(&audio->out_lock);
  185. }
  186. MM_DBG(" audio->out_read = %d audio->out write = %d\n",
  187. audio->out_read, audio->out_write);
  188. ul_reply.reply_hdr.xid = cpu_to_be32(xid);
  189. ul_reply.reply_hdr.type = cpu_to_be32(RPC_TYPE_REPLY);
  190. ul_reply.reply_hdr.reply_stat =
  191. cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
  192. ul_reply.reply_hdr.data.acc_hdr.accept_stat =
  193. cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS);
  194. ul_reply.reply_hdr.data.acc_hdr.verf_flavor = 0;
  195. ul_reply.reply_hdr.data.acc_hdr.verf_length = 0;
  196. ul_reply.valid_pkt_status_ptr = cpu_to_be32(0x00000001);
  197. ul_reply.pkt_status = cpu_to_be32(0x00000000);
  198. rc = msm_rpc_write(audio->rpc_endpt, &ul_reply,
  199. sizeof(ul_reply));
  200. wake_up(&audio->out_wait);
  201. if (rc < 0)
  202. MM_ERR("RPC write for UL response failed %d\n",
  203. rc);
  204. break;
  205. }
  206. case MVS_PACKET_DL_FN_TYPE_PROC:{
  207. struct audio_mvs_dl_reply dl_reply;
  208. MM_DBG("MVS_PACKET_DL_FN_TYPE_PROC\n");
  209. memset(&dl_reply, 0, sizeof(dl_reply));
  210. dl_reply.reply_hdr.xid = cpu_to_be32(xid);
  211. dl_reply.reply_hdr.type = cpu_to_be32(RPC_TYPE_REPLY);
  212. dl_reply.reply_hdr.reply_stat =
  213. cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
  214. dl_reply.reply_hdr.data.acc_hdr.accept_stat =
  215. cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS);
  216. dl_reply.reply_hdr.data.acc_hdr.verf_flavor = 0;
  217. dl_reply.reply_hdr.data.acc_hdr.verf_length = 0;
  218. mutex_lock(&audio->in_lock);
  219. if (audio->in_read < audio->in_write
  220. && audio->dl_play) {
  221. index = audio->in_read % MVS_MAX_Q_LEN;
  222. memcpy(&dl_reply.voc_pkt,
  223. audio->in[index].voc_pkt,
  224. audio->in[index].len);
  225. audio->in_read++;
  226. audio_mvs_info.ack_dl_count++;
  227. dl_reply.pkt_status =
  228. cpu_to_be32(AUDIO_MVS_PKT_NORMAL);
  229. wake_up(&audio->in_wait);
  230. } else {
  231. dl_reply.pkt_status =
  232. cpu_to_be32(AUDIO_MVS_PKT_SLOW);
  233. }
  234. mutex_unlock(&audio->in_lock);
  235. MM_DBG(" audio->in_read = %d audio->in write = %d\n",
  236. audio->in_read, audio->in_write);
  237. dl_reply.valid_frame_info_ptr = cpu_to_be32(0x00000001);
  238. dl_reply.frame_mode = cpu_to_be32(audio->frame_mode);
  239. dl_reply.frame_mode_again =
  240. cpu_to_be32(audio->frame_mode);
  241. dl_reply.frame_info_hdr.frame_mode =
  242. cpu_to_be32(audio->frame_mode);
  243. dl_reply.frame_info_hdr.mvs_mode =
  244. cpu_to_be32(audio->mvs_mode);
  245. dl_reply.frame_info_hdr.buf_free_cnt = 0;
  246. dl_reply.pcm_frame = cpu_to_be32(audio->pcm_frame);
  247. dl_reply.pcm_mode = cpu_to_be32(audio->pcm_mode);
  248. dl_reply.valid_pkt_status_ptr = cpu_to_be32(0x00000001);
  249. rc = msm_rpc_write(audio->rpc_endpt, &dl_reply,
  250. sizeof(dl_reply));
  251. if (rc < 0)
  252. MM_ERR("RPC write for DL response failed %d\n",
  253. rc);
  254. break;
  255. }
  256. default:
  257. MM_ERR("Unknown CB type %d\n", procedure);
  258. }
  259. }
  260. static int audio_mvs_thread(void *data)
  261. {
  262. struct audio_mvs_info_type *audio = &audio_mvs_info;
  263. struct rpc_request_hdr *rpc_hdr = NULL;
  264. struct rpc_reply_hdr *rpc_reply = NULL;
  265. uint32_t reply_status = 0;
  266. uint32_t rpc_type;
  267. int rpc_hdr_len;
  268. MM_DBG("%s\n", __func__);
  269. while (!kthread_should_stop()) {
  270. rpc_hdr_len =
  271. msm_rpc_read(audio->rpc_endpt, (void **)&rpc_hdr, -1, -1);
  272. if (rpc_hdr_len < 0) {
  273. MM_ERR("RPC read failed %d\n", rpc_hdr_len);
  274. break;
  275. } else if (rpc_hdr_len < RPC_COMMON_HDR_SZ)
  276. continue;
  277. else {
  278. rpc_type = be32_to_cpu(rpc_hdr->type);
  279. if (rpc_type == RPC_TYPE_REPLY) {
  280. if (rpc_hdr_len < RPC_REPLY_HDR_SZ)
  281. continue;
  282. rpc_reply = (void *)rpc_hdr;
  283. reply_status = be32_to_cpu(rpc_reply->
  284. reply_stat);
  285. if (reply_status != RPCMSG_REPLYSTAT_ACCEPTED) {
  286. /* If the command is not accepted,
  287. * there will be no response callback.
  288. * Wake the caller and report error. */
  289. audio->rpc_status = RPC_STATUS_REJECT;
  290. wake_up(&audio->wait);
  291. MM_ERR("RPC reply status denied\n");
  292. }
  293. } else if (rpc_type == RPC_TYPE_REQUEST) {
  294. if (rpc_hdr_len < RPC_REQUEST_HDR_SZ)
  295. continue;
  296. MM_DBG("ALSA: kthread call procedure\n");
  297. audio_mvs_process_rpc_request(
  298. be32_to_cpu(rpc_hdr->procedure),
  299. be32_to_cpu(rpc_hdr->xid),
  300. (void *)(rpc_hdr + 1),
  301. (rpc_hdr_len - sizeof(*rpc_hdr)),
  302. audio);
  303. } else
  304. MM_ERR("Unexpected RPC type %d\n", rpc_type);
  305. }
  306. kfree(rpc_hdr);
  307. rpc_hdr = NULL;
  308. }
  309. return 0;
  310. }
  311. static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
  312. {
  313. struct audio_mvs_info_type *audio = &audio_mvs_info;
  314. MM_DBG("%s\n", __func__);
  315. switch (cmd) {
  316. case SNDRV_PCM_TRIGGER_START:
  317. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  318. audio->playback_start = 1;
  319. else
  320. audio->capture_start = 1;
  321. break;
  322. case SNDRV_PCM_TRIGGER_RESUME:
  323. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  324. break;
  325. case SNDRV_PCM_TRIGGER_STOP:
  326. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  327. audio->playback_start = 0;
  328. else
  329. audio->capture_start = 0;
  330. break;
  331. default:
  332. break;
  333. }
  334. return 0;
  335. }
  336. static int msm_pcm_open(struct snd_pcm_substream *substream)
  337. {
  338. int ret = 0;
  339. struct snd_pcm_runtime *runtime = substream->runtime;
  340. struct audio_mvs_info_type *audio = &audio_mvs_info;
  341. MM_DBG("%s\n", __func__);
  342. mutex_lock(&audio->lock);
  343. if (audio->state < AUDIO_MVS_OPENED) {
  344. audio->rpc_endpt =
  345. msm_rpc_connect_compatible(MVS_PROG,
  346. MVS_VERS,
  347. MSM_RPC_UNINTERRUPTIBLE);
  348. audio->state = AUDIO_MVS_OPENED;
  349. }
  350. if (IS_ERR(audio->rpc_endpt)) {
  351. MM_ERR("ALSA MVS RPC connect failed with version 0x%x\n",
  352. MVS_VERS);
  353. ret = PTR_ERR(audio->rpc_endpt);
  354. audio->rpc_endpt = NULL;
  355. goto err;
  356. } else {
  357. MM_DBG("ALSA MVS RPC connect succeeded\n");
  358. if (audio->playback_substream == NULL ||
  359. audio->capture_substream == NULL) {
  360. if (substream->stream ==
  361. SNDRV_PCM_STREAM_PLAYBACK) {
  362. audio->playback_substream =
  363. substream;
  364. runtime->hw = msm_pcm_hardware;
  365. } else if (substream->stream ==
  366. SNDRV_PCM_STREAM_CAPTURE) {
  367. audio->capture_substream =
  368. substream;
  369. runtime->hw = msm_pcm_hardware;
  370. }
  371. } else {
  372. ret = -EPERM;
  373. goto err;
  374. }
  375. ret = snd_pcm_hw_constraint_integer(runtime,
  376. SNDRV_PCM_HW_PARAM_PERIODS);
  377. if (ret < 0) {
  378. MM_ERR("snd_pcm_hw_constraint_integer failed\n");
  379. if (!audio->instance) {
  380. msm_rpc_close(audio->rpc_endpt);
  381. audio->rpc_endpt = NULL;
  382. }
  383. goto err;
  384. }
  385. audio->instance++;
  386. }
  387. err:
  388. mutex_unlock(&audio->lock);
  389. return ret;
  390. }
  391. static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a,
  392. snd_pcm_uframes_t hwoff, void __user *buf,
  393. snd_pcm_uframes_t frames)
  394. {
  395. int rc = 0;
  396. int count = 0;
  397. struct snd_pcm_runtime *runtime = substream->runtime;
  398. struct audio_mvs_info_type *audio = &audio_mvs_info;
  399. uint32_t index;
  400. MM_DBG("%s\n", __func__);
  401. if (audio->dl_play == 1) {
  402. rc = wait_event_interruptible_timeout(audio->in_wait,
  403. (audio->in_write - audio->in_read <= 3),
  404. 100 * HZ);
  405. if (!rc) {
  406. MM_ERR("MVS: write time out\n");
  407. return -ETIMEDOUT;
  408. } else if (rc < 0) {
  409. MM_ERR("MVS: write was interrupted\n");
  410. return -ERESTARTSYS;
  411. }
  412. }
  413. mutex_lock(&audio->in_lock);
  414. if (audio->state == AUDIO_MVS_ENABLED) {
  415. index = audio->in_write % MVS_MAX_Q_LEN;
  416. count = frames_to_bytes(runtime, frames);
  417. if (count <= MVS_MAX_VOC_PKT_SIZE) {
  418. rc = copy_from_user(audio->in[index].voc_pkt, buf,
  419. count);
  420. } else
  421. rc = -ENOMEM;
  422. if (!rc) {
  423. audio->in[index].len = count;
  424. audio->in_write++;
  425. rc = count;
  426. if (audio->in_write >= 3)
  427. audio->dl_play = 1;
  428. } else {
  429. MM_ERR("Copy from user returned %d\n", rc);
  430. rc = -EFAULT;
  431. }
  432. } else {
  433. MM_ERR("Write performed in invalid state %d\n",
  434. audio->state);
  435. rc = -EINVAL;
  436. }
  437. mutex_unlock(&audio->in_lock);
  438. return rc;
  439. }
  440. static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
  441. int channel, snd_pcm_uframes_t hwoff,
  442. void __user *buf, snd_pcm_uframes_t frames)
  443. {
  444. int rc = 0;
  445. int count = 0;
  446. struct snd_pcm_runtime *runtime = substream->runtime;
  447. struct audio_mvs_info_type *audio = &audio_mvs_info;
  448. uint32_t index = 0;
  449. MM_DBG("%s\n", __func__);
  450. /* Ensure the driver has been enabled. */
  451. if (audio->state != AUDIO_MVS_ENABLED) {
  452. MM_ERR("Read performed in invalid state %d\n", audio->state);
  453. return -EPERM;
  454. }
  455. rc = wait_event_interruptible_timeout(audio->out_wait,
  456. (audio->out_read < audio->out_write ||
  457. audio->state == AUDIO_MVS_CLOSING ||
  458. audio->state == AUDIO_MVS_CLOSED),
  459. 100 * HZ);
  460. if (!rc) {
  461. MM_ERR("MVS: No UL data available\n");
  462. return -ETIMEDOUT;
  463. } else if (rc < 0) {
  464. MM_ERR("MVS: Read was interrupted\n");
  465. return -ERESTARTSYS;
  466. }
  467. mutex_lock(&audio->out_lock);
  468. if (audio->state == AUDIO_MVS_CLOSING
  469. || audio->state == AUDIO_MVS_CLOSED) {
  470. rc = -EBUSY;
  471. } else {
  472. count = frames_to_bytes(runtime, frames);
  473. index = audio->out_read % MVS_MAX_Q_LEN;
  474. if (audio->out[index].len <= count) {
  475. rc = copy_to_user(buf,
  476. audio->out[index].voc_pkt,
  477. audio->out[index].len);
  478. if (rc == 0) {
  479. rc = audio->out[index].len;
  480. audio->out_read++;
  481. } else {
  482. MM_ERR("Copy to user %d\n", rc);
  483. rc = -EFAULT;
  484. }
  485. } else
  486. rc = -ENOMEM;
  487. }
  488. mutex_unlock(&audio->out_lock);
  489. return rc;
  490. }
  491. static int msm_pcm_copy(struct snd_pcm_substream *substream, int a,
  492. snd_pcm_uframes_t hwoff, void __user *buf,
  493. snd_pcm_uframes_t frames)
  494. {
  495. int ret = 0;
  496. MM_DBG("%s\n", __func__);
  497. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  498. ret = msm_pcm_playback_copy(substream, a, hwoff, buf, frames);
  499. else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  500. ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames);
  501. return ret;
  502. }
  503. static int msm_pcm_close(struct snd_pcm_substream *substream)
  504. {
  505. int rc = 0;
  506. struct audio_mvs_info_type *audio = &audio_mvs_info;
  507. struct audio_mvs_release_msg release_msg;
  508. MM_DBG("%s\n", __func__);
  509. memset(&release_msg, 0, sizeof(release_msg));
  510. mutex_lock(&audio->lock);
  511. audio->instance--;
  512. wake_up(&audio->out_wait);
  513. if (!audio->instance) {
  514. if (audio->state == AUDIO_MVS_ENABLED) {
  515. audio->state = AUDIO_MVS_CLOSING;
  516. /* Release MVS. */
  517. release_msg.client_id = cpu_to_be32(MVS_CLIENT_ID_VOIP);
  518. msm_rpc_setup_req(&release_msg.rpc_hdr, audio->rpc_prog,
  519. audio->rpc_ver,
  520. MVS_RELEASE_PROC);
  521. audio->rpc_status = RPC_STATUS_FAILURE;
  522. rc = msm_rpc_write(audio->rpc_endpt, &release_msg,
  523. sizeof(release_msg));
  524. if (rc >= 0) {
  525. MM_DBG("RPC write for release done\n");
  526. rc = wait_event_timeout(audio->wait,
  527. (audio->rpc_status !=
  528. RPC_STATUS_FAILURE), 1 * HZ);
  529. if (rc != 0) {
  530. MM_DBG
  531. ("Wait event for release succeeded\n");
  532. rc = 0;
  533. kthread_stop(audio->task);
  534. audio->prepare_ack = 0;
  535. audio->task = NULL;
  536. del_timer_sync(&audio->timer);
  537. } else {
  538. MM_ERR
  539. ("Wait event for release failed %d\n",
  540. rc);
  541. }
  542. } else {
  543. MM_ERR("RPC write for release failed %d\n", rc);
  544. }
  545. }
  546. audio->state = AUDIO_MVS_CLOSED;
  547. msm_rpc_close(audio->rpc_endpt);
  548. audio->rpc_endpt = NULL;
  549. }
  550. mutex_unlock(&audio->lock);
  551. wake_unlock(&audio->suspend_lock);
  552. pm_qos_update_request(&audio->pm_qos_req, PM_QOS_DEFAULT_VALUE);
  553. /* Release the IO buffers. */
  554. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  555. mutex_lock(&audio->in_lock);
  556. audio->in_write = 0;
  557. audio->in_read = 0;
  558. audio->playback_enable = 0;
  559. audio->dl_play = 0;
  560. audio->ack_dl_count = 0;
  561. memset(audio->in[0].voc_pkt, 0,
  562. MVS_MAX_VOC_PKT_SIZE * MVS_MAX_Q_LEN);
  563. audio->in->len = 0;
  564. audio->playback_substream = NULL;
  565. mutex_unlock(&audio->in_lock);
  566. } else {
  567. mutex_lock(&audio->out_lock);
  568. audio->out_write = 0;
  569. audio->out_read = 0;
  570. audio->capture_enable = 0;
  571. audio->ack_ul_count = 0;
  572. memset(audio->out[0].voc_pkt, 0,
  573. MVS_MAX_VOC_PKT_SIZE * MVS_MAX_Q_LEN);
  574. audio->out->len = 0;
  575. audio->capture_substream = NULL;
  576. mutex_unlock(&audio->out_lock);
  577. }
  578. return rc;
  579. }
  580. static int msm_mvs_pcm_setup(struct snd_pcm_substream *substream)
  581. {
  582. int rc = 0;
  583. struct audio_mvs_acquire_msg acquire_msg;
  584. struct audio_mvs_info_type *audio = &audio_mvs_info;
  585. memset(&acquire_msg, 0, sizeof(acquire_msg));
  586. /*Create an Kthread */
  587. MM_DBG("ALSA MVS thread creating\n");
  588. if (!IS_ERR(audio->rpc_endpt)) {
  589. audio->task =
  590. kthread_run(audio_mvs_thread, audio,
  591. "audio_alsa_mvs_thread");
  592. if (!IS_ERR(audio->task)) {
  593. MM_DBG("ALSA MVS thread create succeeded\n");
  594. audio->rpc_prog = MVS_PROG;
  595. audio->rpc_ver = MVS_VERS;
  596. /* Acquire MVS. */
  597. acquire_msg.acquire_args.client_id =
  598. cpu_to_be32(MVS_CLIENT_ID_VOIP);
  599. acquire_msg.acquire_args.cb_func_id =
  600. cpu_to_be32(MVS_CB_FUNC_ID);
  601. msm_rpc_setup_req(&acquire_msg.rpc_hdr,
  602. audio->rpc_prog,
  603. audio->rpc_ver,
  604. MVS_ACQUIRE_PROC);
  605. audio->rpc_status = RPC_STATUS_FAILURE;
  606. rc = msm_rpc_write(audio->rpc_endpt,
  607. &acquire_msg, sizeof(acquire_msg));
  608. if (rc >= 0) {
  609. MM_DBG("RPC write for acquire done\n");
  610. rc = wait_event_timeout(audio->wait,
  611. (audio->rpc_status !=
  612. RPC_STATUS_FAILURE),
  613. 1 * HZ);
  614. if (rc != 0) {
  615. audio->state =
  616. AUDIO_MVS_ACQUIRE;
  617. rc = 0;
  618. MM_DBG
  619. ("MVS driver in acquire state\n");
  620. } else {
  621. MM_ERR
  622. ("acquire Wait event failed %d\n",
  623. rc);
  624. rc = -EBUSY;
  625. }
  626. } else {
  627. MM_ERR("RPC write for acquire failed %d\n",
  628. rc);
  629. rc = -EBUSY;
  630. }
  631. } else {
  632. MM_ERR("ALSA MVS thread create failed\n");
  633. rc = PTR_ERR(audio->task);
  634. audio->task = NULL;
  635. msm_rpc_close(audio->rpc_endpt);
  636. audio->rpc_endpt = NULL;
  637. }
  638. } else {
  639. MM_ERR("RPC connect is not setup with version 0x%x\n",
  640. MVS_VERS);
  641. rc = PTR_ERR(audio->rpc_endpt);
  642. audio->rpc_endpt = NULL;
  643. }
  644. /*mvs mode setup */
  645. if (audio->state == AUDIO_MVS_ACQUIRE)
  646. rc = audio_mvs_setup_mvs(audio);
  647. else
  648. rc = -EBUSY;
  649. return rc;
  650. }
  651. static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
  652. {
  653. struct audio_mvs_info_type *prtd = &audio_mvs_info;
  654. MM_DBG("%s\n", __func__);
  655. prtd->pcm_playback_irq_pos = 0;
  656. prtd->pcm_playback_buf_pos = 0;
  657. /* rate and channels are sent to audio driver */
  658. prtd->playback_enable = 1;
  659. return 0;
  660. }
  661. static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
  662. {
  663. struct audio_mvs_info_type *prtd = &audio_mvs_info;
  664. prtd->pcm_capture_size = snd_pcm_lib_buffer_bytes(substream);
  665. prtd->pcm_capture_count = snd_pcm_lib_period_bytes(substream);
  666. prtd->pcm_capture_irq_pos = 0;
  667. prtd->pcm_capture_buf_pos = 0;
  668. prtd->capture_enable = 1;
  669. return 0;
  670. }
  671. static int msm_pcm_prepare(struct snd_pcm_substream *substream)
  672. {
  673. int rc = 0;
  674. struct snd_pcm_runtime *runtime = substream->runtime;
  675. struct audio_mvs_info_type *prtd = &audio_mvs_info;
  676. unsigned long expiry = 0;
  677. MM_DBG("%s\n", __func__);
  678. prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
  679. prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
  680. mutex_lock(&prtd->prepare_lock);
  681. if (prtd->state == AUDIO_MVS_ENABLED)
  682. goto enabled;
  683. else if (prtd->state == AUDIO_MVS_PREPARING)
  684. goto prepairing;
  685. else if (prtd->state == AUDIO_MVS_OPENED) {
  686. prtd->state = AUDIO_MVS_PREPARING;
  687. rc = msm_mvs_pcm_setup(substream);
  688. }
  689. if (!rc) {
  690. expiry = ((unsigned long)((prtd->pcm_count * 1000)
  691. /(runtime->rate * runtime->channels * 2)));
  692. expiry -= (expiry % 10);
  693. prtd->timer.expires = jiffies + (msecs_to_jiffies(expiry));
  694. prtd->expiry_delta = (msecs_to_jiffies(expiry));
  695. if (prtd->expiry_delta <= 2)
  696. prtd->expiry_delta = 1;
  697. setup_timer(&prtd->timer, snd_pcm_mvs_timer,
  698. (unsigned long)prtd);
  699. prtd->ack_ul_count = 0;
  700. prtd->ack_dl_count = 0;
  701. add_timer(&prtd->timer);
  702. } else {
  703. MM_ERR("ALSA MVS setup is not done");
  704. rc = -EPERM;
  705. prtd->state = AUDIO_MVS_OPENED;
  706. goto err;
  707. }
  708. prepairing:
  709. rc = wait_event_interruptible(prtd->prepare_wait,
  710. (prtd->prepare_ack == 2));
  711. if (rc < 0) {
  712. MM_ERR("Wait event for prepare faild rc %d", rc);
  713. rc = -EINTR;
  714. prtd->state = AUDIO_MVS_OPENED;
  715. goto err;
  716. } else
  717. MM_DBG("Wait event for prepare succeeded\n");
  718. prtd->state = AUDIO_MVS_ENABLED;
  719. enabled:
  720. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  721. rc = msm_pcm_playback_prepare(substream);
  722. else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  723. rc = msm_pcm_capture_prepare(substream);
  724. err:
  725. mutex_unlock(&prtd->prepare_lock);
  726. return rc;
  727. }
  728. int msm_mvs_pcm_hw_params(struct snd_pcm_substream *substream,
  729. struct snd_pcm_hw_params *params)
  730. {
  731. struct snd_pcm_runtime *runtime = substream->runtime;
  732. MM_DBG("%s\n", __func__);
  733. if (substream->pcm->device & 1) {
  734. runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
  735. runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
  736. }
  737. return 0;
  738. }
  739. static snd_pcm_uframes_t
  740. msm_pcm_playback_pointer(struct snd_pcm_substream *substream)
  741. {
  742. struct snd_pcm_runtime *runtime = substream->runtime;
  743. struct audio_mvs_info_type *audio = &audio_mvs_info;
  744. if (audio->pcm_playback_irq_pos >= audio->pcm_size)
  745. audio->pcm_playback_irq_pos = 0;
  746. return bytes_to_frames(runtime, (audio->pcm_playback_irq_pos));
  747. }
  748. static snd_pcm_uframes_t
  749. msm_pcm_capture_pointer(struct snd_pcm_substream *substream)
  750. {
  751. struct snd_pcm_runtime *runtime = substream->runtime;
  752. struct audio_mvs_info_type *audio = &audio_mvs_info;
  753. if (audio->pcm_capture_irq_pos >= audio->pcm_capture_size)
  754. audio->pcm_capture_irq_pos = 0;
  755. return bytes_to_frames(runtime, (audio->pcm_capture_irq_pos));
  756. }
  757. static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
  758. {
  759. snd_pcm_uframes_t ret = 0;
  760. MM_DBG("%s\n", __func__);
  761. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  762. ret = msm_pcm_playback_pointer(substream);
  763. else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  764. ret = msm_pcm_capture_pointer(substream);
  765. return ret;
  766. }
  767. static struct snd_pcm_ops msm_mvs_pcm_ops = {
  768. .open = msm_pcm_open,
  769. .copy = msm_pcm_copy,
  770. .hw_params = msm_mvs_pcm_hw_params,
  771. .close = msm_pcm_close,
  772. .ioctl = snd_pcm_lib_ioctl,
  773. .prepare = msm_pcm_prepare,
  774. .trigger = msm_pcm_trigger,
  775. .pointer = msm_pcm_pointer,
  776. };
  777. static int msm_pcm_new(struct snd_soc_pcm_runtime *rtd)
  778. {
  779. int i, ret, offset = 0;
  780. struct snd_pcm *pcm = rtd->pcm;
  781. audio_mvs_info.mem_chunk = kmalloc(
  782. 2 * MVS_MAX_VOC_PKT_SIZE * MVS_MAX_Q_LEN, GFP_KERNEL);
  783. if (audio_mvs_info.mem_chunk != NULL) {
  784. audio_mvs_info.in_read = 0;
  785. audio_mvs_info.in_write = 0;
  786. audio_mvs_info.out_read = 0;
  787. audio_mvs_info.out_write = 0;
  788. for (i = 0; i < MVS_MAX_Q_LEN; i++) {
  789. audio_mvs_info.in[i].voc_pkt =
  790. audio_mvs_info.mem_chunk + offset;
  791. offset = offset + MVS_MAX_VOC_PKT_SIZE;
  792. }
  793. for (i = 0; i < MVS_MAX_Q_LEN; i++) {
  794. audio_mvs_info.out[i].voc_pkt =
  795. audio_mvs_info.mem_chunk + offset;
  796. offset = offset + MVS_MAX_VOC_PKT_SIZE;
  797. }
  798. audio_mvs_info.playback_substream = NULL;
  799. audio_mvs_info.capture_substream = NULL;
  800. } else {
  801. MM_ERR("MSM MVS kmalloc failed\n");
  802. return -ENODEV;
  803. }
  804. ret = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, 1);
  805. if (ret)
  806. return ret;
  807. ret = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, 1);
  808. if (ret)
  809. return ret;
  810. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &msm_mvs_pcm_ops);
  811. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &msm_mvs_pcm_ops);
  812. return 0;
  813. }
  814. struct snd_soc_platform_driver msm_mvs_soc_platform = {
  815. .ops = &msm_mvs_pcm_ops,
  816. .pcm_new = msm_pcm_new,
  817. };
  818. EXPORT_SYMBOL(msm_mvs_soc_platform);
  819. static __devinit int msm_pcm_probe(struct platform_device *pdev)
  820. {
  821. return snd_soc_register_platform(&pdev->dev,
  822. &msm_mvs_soc_platform);
  823. }
  824. static int msm_pcm_remove(struct platform_device *pdev)
  825. {
  826. snd_soc_unregister_platform(&pdev->dev);
  827. return 0;
  828. }
  829. static struct platform_driver msm_pcm_driver = {
  830. .driver = {
  831. .name = "msm-mvs-audio",
  832. .owner = THIS_MODULE,
  833. },
  834. .probe = msm_pcm_probe,
  835. .remove = __devexit_p(msm_pcm_remove),
  836. };
  837. static int __init msm_mvs_soc_platform_init(void)
  838. {
  839. memset(&audio_mvs_info, 0, sizeof(audio_mvs_info));
  840. mutex_init(&audio_mvs_info.lock);
  841. mutex_init(&audio_mvs_info.prepare_lock);
  842. mutex_init(&audio_mvs_info.in_lock);
  843. mutex_init(&audio_mvs_info.out_lock);
  844. init_waitqueue_head(&audio_mvs_info.wait);
  845. init_waitqueue_head(&audio_mvs_info.prepare_wait);
  846. init_waitqueue_head(&audio_mvs_info.out_wait);
  847. init_waitqueue_head(&audio_mvs_info.in_wait);
  848. wake_lock_init(&audio_mvs_info.suspend_lock, WAKE_LOCK_SUSPEND,
  849. "audio_mvs_suspend");
  850. pm_qos_add_request(&audio_mvs_info.pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
  851. PM_QOS_DEFAULT_VALUE);
  852. return platform_driver_register(&msm_pcm_driver);
  853. }
  854. module_init(msm_mvs_soc_platform_init);
  855. static void __exit msm_mvs_soc_platform_exit(void)
  856. {
  857. platform_driver_unregister(&msm_pcm_driver);
  858. }
  859. module_exit(msm_mvs_soc_platform_exit);
  860. MODULE_DESCRIPTION("MVS PCM module platform driver");
  861. MODULE_LICENSE("GPL v2");