audio_hwacc_effects.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. /*
  2. * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/msm_audio.h>
  14. #include <linux/compat.h>
  15. #include "q6audio_common.h"
  16. #include <dsp/msm-audio-effects-q6-v2.h>
  17. #include "audio_utils_aio.h"
  18. #define MAX_CHANNELS_SUPPORTED 8
  19. #define WAIT_TIMEDOUT_DURATION_SECS 1
  20. struct q6audio_effects {
  21. wait_queue_head_t read_wait;
  22. wait_queue_head_t write_wait;
  23. struct audio_client *ac;
  24. struct msm_hwacc_effects_config config;
  25. struct mutex lock;
  26. atomic_t in_count;
  27. atomic_t out_count;
  28. int opened;
  29. int started;
  30. int buf_alloc;
  31. struct msm_nt_eff_all_config audio_effects;
  32. };
  33. static void audio_effects_init_pp(struct audio_client *ac)
  34. {
  35. int ret = 0;
  36. struct asm_softvolume_params softvol = {
  37. .period = SOFT_VOLUME_PERIOD,
  38. .step = SOFT_VOLUME_STEP,
  39. .rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
  40. };
  41. if (!ac) {
  42. pr_err("%s: audio client null to init pp\n", __func__);
  43. return;
  44. }
  45. ret = q6asm_set_softvolume_v2(ac, &softvol,
  46. SOFT_VOLUME_INSTANCE_1);
  47. if (ret < 0)
  48. pr_err("%s: Send SoftVolume Param failed ret=%d\n",
  49. __func__, ret);
  50. }
  51. static void audio_effects_deinit_pp(struct audio_client *ac)
  52. {
  53. if (!ac) {
  54. pr_err("%s: audio client null to deinit pp\n", __func__);
  55. return;
  56. }
  57. }
  58. static void audio_effects_event_handler(uint32_t opcode, uint32_t token,
  59. uint32_t *payload, void *priv)
  60. {
  61. struct q6audio_effects *effects;
  62. if (!payload || !priv) {
  63. pr_err("%s: invalid data to handle events, payload: %pK, priv: %pK\n",
  64. __func__, payload, priv);
  65. return;
  66. }
  67. effects = (struct q6audio_effects *)priv;
  68. switch (opcode) {
  69. case ASM_DATA_EVENT_WRITE_DONE_V2: {
  70. atomic_inc(&effects->out_count);
  71. wake_up(&effects->write_wait);
  72. break;
  73. }
  74. case ASM_DATA_EVENT_READ_DONE_V2: {
  75. atomic_inc(&effects->in_count);
  76. wake_up(&effects->read_wait);
  77. break;
  78. }
  79. case APR_BASIC_RSP_RESULT: {
  80. pr_debug("%s: APR_BASIC_RSP_RESULT Cmd[0x%x] Status[0x%x]\n",
  81. __func__, payload[0], payload[1]);
  82. switch (payload[0]) {
  83. case ASM_SESSION_CMD_RUN_V2:
  84. pr_debug("ASM_SESSION_CMD_RUN_V2\n");
  85. break;
  86. default:
  87. pr_debug("%s: Payload = [0x%x] stat[0x%x]\n",
  88. __func__, payload[0], payload[1]);
  89. break;
  90. }
  91. break;
  92. }
  93. default:
  94. pr_debug("%s: Unhandled Event 0x%x token = 0x%x\n",
  95. __func__, opcode, token);
  96. break;
  97. }
  98. }
  99. static int audio_effects_shared_ioctl(struct file *file, unsigned int cmd,
  100. unsigned long arg)
  101. {
  102. struct q6audio_effects *effects = file->private_data;
  103. int rc = 0;
  104. switch (cmd) {
  105. case AUDIO_START: {
  106. pr_debug("%s: AUDIO_START\n", __func__);
  107. mutex_lock(&effects->lock);
  108. rc = q6asm_open_read_write_v2(effects->ac,
  109. FORMAT_LINEAR_PCM,
  110. FORMAT_MULTI_CHANNEL_LINEAR_PCM,
  111. effects->config.meta_mode_enabled,
  112. effects->config.output.bits_per_sample,
  113. true /*overwrite topology*/,
  114. ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER);
  115. if (rc < 0) {
  116. pr_err("%s: Open failed for hw accelerated effects:rc=%d\n",
  117. __func__, rc);
  118. rc = -EINVAL;
  119. mutex_unlock(&effects->lock);
  120. goto ioctl_fail;
  121. }
  122. effects->opened = 1;
  123. pr_debug("%s: dec buf size: %d, num_buf: %d, enc buf size: %d, num_buf: %d\n",
  124. __func__, effects->config.output.buf_size,
  125. effects->config.output.num_buf,
  126. effects->config.input.buf_size,
  127. effects->config.input.num_buf);
  128. rc = q6asm_audio_client_buf_alloc_contiguous(IN, effects->ac,
  129. effects->config.output.buf_size,
  130. effects->config.output.num_buf);
  131. if (rc < 0) {
  132. pr_err("%s: Write buffer Allocation failed rc = %d\n",
  133. __func__, rc);
  134. rc = -ENOMEM;
  135. mutex_unlock(&effects->lock);
  136. goto ioctl_fail;
  137. }
  138. atomic_set(&effects->in_count, effects->config.input.num_buf);
  139. rc = q6asm_audio_client_buf_alloc_contiguous(OUT, effects->ac,
  140. effects->config.input.buf_size,
  141. effects->config.input.num_buf);
  142. if (rc < 0) {
  143. pr_err("%s: Read buffer Allocation failed rc = %d\n",
  144. __func__, rc);
  145. rc = -ENOMEM;
  146. goto readbuf_fail;
  147. }
  148. atomic_set(&effects->out_count, effects->config.output.num_buf);
  149. effects->buf_alloc = 1;
  150. pr_debug("%s: enc: sample_rate: %d, num_channels: %d\n",
  151. __func__, effects->config.input.sample_rate,
  152. effects->config.input.num_channels);
  153. rc = q6asm_enc_cfg_blk_pcm(effects->ac,
  154. effects->config.input.sample_rate,
  155. effects->config.input.num_channels);
  156. if (rc < 0) {
  157. pr_err("%s: pcm read block config failed\n", __func__);
  158. rc = -EINVAL;
  159. goto cfg_fail;
  160. }
  161. pr_debug("%s: dec: sample_rate: %d, num_channels: %d, bit_width: %d\n",
  162. __func__, effects->config.output.sample_rate,
  163. effects->config.output.num_channels,
  164. effects->config.output.bits_per_sample);
  165. rc = q6asm_media_format_block_pcm_format_support(
  166. effects->ac, effects->config.output.sample_rate,
  167. effects->config.output.num_channels,
  168. effects->config.output.bits_per_sample);
  169. if (rc < 0) {
  170. pr_err("%s: pcm write format block config failed\n",
  171. __func__);
  172. rc = -EINVAL;
  173. goto cfg_fail;
  174. }
  175. audio_effects_init_pp(effects->ac);
  176. rc = q6asm_run(effects->ac, 0x00, 0x00, 0x00);
  177. if (!rc)
  178. effects->started = 1;
  179. else {
  180. effects->started = 0;
  181. pr_err("%s: ASM run state failed\n", __func__);
  182. }
  183. mutex_unlock(&effects->lock);
  184. break;
  185. }
  186. case AUDIO_EFFECTS_WRITE: {
  187. char *bufptr = NULL;
  188. uint32_t idx = 0;
  189. uint32_t size = 0;
  190. mutex_lock(&effects->lock);
  191. if (!effects->started) {
  192. rc = -EFAULT;
  193. mutex_unlock(&effects->lock);
  194. goto ioctl_fail;
  195. }
  196. rc = wait_event_timeout(effects->write_wait,
  197. atomic_read(&effects->out_count),
  198. WAIT_TIMEDOUT_DURATION_SECS * HZ);
  199. if (!rc) {
  200. pr_err("%s: write wait_event_timeout\n", __func__);
  201. rc = -EFAULT;
  202. mutex_unlock(&effects->lock);
  203. goto ioctl_fail;
  204. }
  205. if (!atomic_read(&effects->out_count)) {
  206. pr_err("%s: pcm stopped out_count 0\n", __func__);
  207. rc = -EFAULT;
  208. mutex_unlock(&effects->lock);
  209. goto ioctl_fail;
  210. }
  211. bufptr = q6asm_is_cpu_buf_avail(IN, effects->ac, &size, &idx);
  212. if (bufptr) {
  213. if ((effects->config.buf_cfg.output_len > size) ||
  214. copy_from_user(bufptr, (void *)arg,
  215. effects->config.buf_cfg.output_len)) {
  216. rc = -EFAULT;
  217. mutex_unlock(&effects->lock);
  218. goto ioctl_fail;
  219. }
  220. rc = q6asm_write(effects->ac,
  221. effects->config.buf_cfg.output_len,
  222. 0, 0, NO_TIMESTAMP);
  223. if (rc < 0) {
  224. rc = -EFAULT;
  225. mutex_unlock(&effects->lock);
  226. goto ioctl_fail;
  227. }
  228. atomic_dec(&effects->out_count);
  229. } else {
  230. pr_err("%s: AUDIO_EFFECTS_WRITE: Buffer dropped\n",
  231. __func__);
  232. }
  233. mutex_unlock(&effects->lock);
  234. break;
  235. }
  236. case AUDIO_EFFECTS_READ: {
  237. char *bufptr = NULL;
  238. uint32_t idx = 0;
  239. uint32_t size = 0;
  240. mutex_lock(&effects->lock);
  241. if (!effects->started) {
  242. rc = -EFAULT;
  243. mutex_unlock(&effects->lock);
  244. goto ioctl_fail;
  245. }
  246. atomic_set(&effects->in_count, 0);
  247. q6asm_read_v2(effects->ac, effects->config.buf_cfg.input_len);
  248. /* Read might fail initially, don't error out */
  249. if (rc < 0)
  250. pr_err("%s: read failed\n", __func__);
  251. rc = wait_event_timeout(effects->read_wait,
  252. atomic_read(&effects->in_count),
  253. WAIT_TIMEDOUT_DURATION_SECS * HZ);
  254. if (!rc) {
  255. pr_err("%s: read wait_event_timeout\n", __func__);
  256. rc = -EFAULT;
  257. mutex_unlock(&effects->lock);
  258. goto ioctl_fail;
  259. }
  260. if (!atomic_read(&effects->in_count)) {
  261. pr_err("%s: pcm stopped in_count 0\n", __func__);
  262. rc = -EFAULT;
  263. mutex_unlock(&effects->lock);
  264. goto ioctl_fail;
  265. }
  266. bufptr = q6asm_is_cpu_buf_avail(OUT, effects->ac, &size, &idx);
  267. if (bufptr) {
  268. if (!((void *)arg)) {
  269. rc = -EFAULT;
  270. mutex_unlock(&effects->lock);
  271. goto ioctl_fail;
  272. }
  273. if ((effects->config.buf_cfg.input_len > size) ||
  274. copy_to_user((void *)arg, bufptr,
  275. effects->config.buf_cfg.input_len)) {
  276. rc = -EFAULT;
  277. mutex_unlock(&effects->lock);
  278. goto ioctl_fail;
  279. }
  280. }
  281. mutex_unlock(&effects->lock);
  282. break;
  283. }
  284. default:
  285. pr_err("%s: Invalid effects config module\n", __func__);
  286. rc = -EINVAL;
  287. break;
  288. }
  289. ioctl_fail:
  290. return rc;
  291. readbuf_fail:
  292. q6asm_audio_client_buf_free_contiguous(IN,
  293. effects->ac);
  294. mutex_unlock(&effects->lock);
  295. return rc;
  296. cfg_fail:
  297. q6asm_audio_client_buf_free_contiguous(IN,
  298. effects->ac);
  299. q6asm_audio_client_buf_free_contiguous(OUT,
  300. effects->ac);
  301. effects->buf_alloc = 0;
  302. mutex_unlock(&effects->lock);
  303. return rc;
  304. }
  305. static long audio_effects_set_pp_param(struct q6audio_effects *effects,
  306. long *values)
  307. {
  308. int rc = 0;
  309. int effects_module = values[0];
  310. switch (effects_module) {
  311. case VIRTUALIZER_MODULE:
  312. pr_debug("%s: VIRTUALIZER_MODULE\n", __func__);
  313. if (msm_audio_effects_is_effmodule_supp_in_top(
  314. effects_module, effects->ac->topology))
  315. msm_audio_effects_virtualizer_handler(
  316. effects->ac,
  317. &(effects->audio_effects.virtualizer),
  318. (long *)&values[1]);
  319. break;
  320. case REVERB_MODULE:
  321. pr_debug("%s: REVERB_MODULE\n", __func__);
  322. if (msm_audio_effects_is_effmodule_supp_in_top(
  323. effects_module, effects->ac->topology))
  324. msm_audio_effects_reverb_handler(effects->ac,
  325. &(effects->audio_effects.reverb),
  326. (long *)&values[1]);
  327. break;
  328. case BASS_BOOST_MODULE:
  329. pr_debug("%s: BASS_BOOST_MODULE\n", __func__);
  330. if (msm_audio_effects_is_effmodule_supp_in_top(
  331. effects_module, effects->ac->topology))
  332. msm_audio_effects_bass_boost_handler(
  333. effects->ac,
  334. &(effects->audio_effects.bass_boost),
  335. (long *)&values[1]);
  336. break;
  337. case PBE_MODULE:
  338. pr_debug("%s: PBE_MODULE\n", __func__);
  339. if (msm_audio_effects_is_effmodule_supp_in_top(
  340. effects_module, effects->ac->topology))
  341. msm_audio_effects_pbe_handler(
  342. effects->ac,
  343. &(effects->audio_effects.pbe),
  344. (long *)&values[1]);
  345. break;
  346. case EQ_MODULE:
  347. pr_debug("%s: EQ_MODULE\n", __func__);
  348. if (msm_audio_effects_is_effmodule_supp_in_top(
  349. effects_module, effects->ac->topology))
  350. msm_audio_effects_popless_eq_handler(
  351. effects->ac,
  352. &(effects->audio_effects.equalizer),
  353. (long *)&values[1]);
  354. break;
  355. case SOFT_VOLUME_MODULE:
  356. pr_debug("%s: SA PLUS VOLUME_MODULE\n", __func__);
  357. msm_audio_effects_volume_handler_v2(effects->ac,
  358. &(effects->audio_effects.saplus_vol),
  359. (long *)&values[1], SOFT_VOLUME_INSTANCE_1);
  360. break;
  361. case SOFT_VOLUME2_MODULE:
  362. pr_debug("%s: TOPOLOGY SWITCH VOLUME MODULE\n",
  363. __func__);
  364. if (msm_audio_effects_is_effmodule_supp_in_top(
  365. effects_module, effects->ac->topology))
  366. msm_audio_effects_volume_handler_v2(effects->ac,
  367. &(effects->audio_effects.topo_switch_vol),
  368. (long *)&values[1], SOFT_VOLUME_INSTANCE_2);
  369. break;
  370. default:
  371. pr_err("%s: Invalid effects config module\n", __func__);
  372. rc = -EINVAL;
  373. }
  374. return rc;
  375. }
  376. static long audio_effects_ioctl(struct file *file, unsigned int cmd,
  377. unsigned long arg)
  378. {
  379. struct q6audio_effects *effects = file->private_data;
  380. int rc = 0;
  381. long argvalues[MAX_PP_PARAMS_SZ] = {0};
  382. switch (cmd) {
  383. case AUDIO_SET_EFFECTS_CONFIG: {
  384. pr_debug("%s: AUDIO_SET_EFFECTS_CONFIG\n", __func__);
  385. mutex_lock(&effects->lock);
  386. memset(&effects->config, 0, sizeof(effects->config));
  387. if (copy_from_user(&effects->config, (void *)arg,
  388. sizeof(effects->config))) {
  389. pr_err("%s: copy from user for AUDIO_SET_EFFECTS_CONFIG failed\n",
  390. __func__);
  391. rc = -EFAULT;
  392. }
  393. pr_debug("%s: write buf_size: %d, num_buf: %d, sample_rate: %d, channel: %d\n",
  394. __func__, effects->config.output.buf_size,
  395. effects->config.output.num_buf,
  396. effects->config.output.sample_rate,
  397. effects->config.output.num_channels);
  398. pr_debug("%s: read buf_size: %d, num_buf: %d, sample_rate: %d, channel: %d\n",
  399. __func__, effects->config.input.buf_size,
  400. effects->config.input.num_buf,
  401. effects->config.input.sample_rate,
  402. effects->config.input.num_channels);
  403. mutex_unlock(&effects->lock);
  404. break;
  405. }
  406. case AUDIO_EFFECTS_SET_BUF_LEN: {
  407. mutex_lock(&effects->lock);
  408. if (copy_from_user(&effects->config.buf_cfg, (void *)arg,
  409. sizeof(effects->config.buf_cfg))) {
  410. pr_err("%s: copy from user for AUDIO_EFFECTS_SET_BUF_LEN failed\n",
  411. __func__);
  412. rc = -EFAULT;
  413. }
  414. pr_debug("%s: write buf len: %d, read buf len: %d\n",
  415. __func__, effects->config.buf_cfg.output_len,
  416. effects->config.buf_cfg.input_len);
  417. mutex_unlock(&effects->lock);
  418. break;
  419. }
  420. case AUDIO_EFFECTS_GET_BUF_AVAIL: {
  421. struct msm_hwacc_buf_avail buf_avail;
  422. buf_avail.input_num_avail = atomic_read(&effects->in_count);
  423. buf_avail.output_num_avail = atomic_read(&effects->out_count);
  424. mutex_lock(&effects->lock);
  425. pr_debug("%s: write buf avail: %d, read buf avail: %d\n",
  426. __func__, buf_avail.output_num_avail,
  427. buf_avail.input_num_avail);
  428. if (copy_to_user((void *)arg, &buf_avail,
  429. sizeof(buf_avail))) {
  430. pr_err("%s: copy to user for AUDIO_EFFECTS_GET_NUM_BUF_AVAIL failed\n",
  431. __func__);
  432. rc = -EFAULT;
  433. }
  434. mutex_unlock(&effects->lock);
  435. break;
  436. }
  437. case AUDIO_EFFECTS_SET_PP_PARAMS: {
  438. mutex_lock(&effects->lock);
  439. if (copy_from_user(argvalues, (void *)arg,
  440. MAX_PP_PARAMS_SZ*sizeof(long))) {
  441. pr_err("%s: copy from user for pp params failed\n",
  442. __func__);
  443. mutex_unlock(&effects->lock);
  444. return -EFAULT;
  445. }
  446. rc = audio_effects_set_pp_param(effects, argvalues);
  447. mutex_unlock(&effects->lock);
  448. break;
  449. }
  450. default:
  451. pr_debug("%s: Calling shared ioctl\n", __func__);
  452. rc = audio_effects_shared_ioctl(file, cmd, arg);
  453. break;
  454. }
  455. if (rc)
  456. pr_err("%s: cmd 0x%x failed\n", __func__, cmd);
  457. return rc;
  458. }
  459. #ifdef CONFIG_COMPAT
  460. struct msm_hwacc_data_config32 {
  461. __u32 buf_size;
  462. __u32 num_buf;
  463. __u32 num_channels;
  464. __u8 channel_map[MAX_CHANNELS_SUPPORTED];
  465. __u32 sample_rate;
  466. __u32 bits_per_sample;
  467. };
  468. struct msm_hwacc_buf_cfg32 {
  469. __u32 input_len;
  470. __u32 output_len;
  471. };
  472. struct msm_hwacc_buf_avail32 {
  473. __u32 input_num_avail;
  474. __u32 output_num_avail;
  475. };
  476. struct msm_hwacc_effects_config32 {
  477. struct msm_hwacc_data_config32 input;
  478. struct msm_hwacc_data_config32 output;
  479. struct msm_hwacc_buf_cfg32 buf_cfg;
  480. __u32 meta_mode_enabled;
  481. __u32 overwrite_topology;
  482. __s32 topology;
  483. };
  484. enum {
  485. AUDIO_SET_EFFECTS_CONFIG32 = _IOW(AUDIO_IOCTL_MAGIC, 99,
  486. struct msm_hwacc_effects_config32),
  487. AUDIO_EFFECTS_SET_BUF_LEN32 = _IOW(AUDIO_IOCTL_MAGIC, 100,
  488. struct msm_hwacc_buf_cfg32),
  489. AUDIO_EFFECTS_GET_BUF_AVAIL32 = _IOW(AUDIO_IOCTL_MAGIC, 101,
  490. struct msm_hwacc_buf_avail32),
  491. AUDIO_EFFECTS_WRITE32 = _IOW(AUDIO_IOCTL_MAGIC, 102, compat_uptr_t),
  492. AUDIO_EFFECTS_READ32 = _IOWR(AUDIO_IOCTL_MAGIC, 103, compat_uptr_t),
  493. AUDIO_EFFECTS_SET_PP_PARAMS32 = _IOW(AUDIO_IOCTL_MAGIC, 104,
  494. compat_uptr_t),
  495. AUDIO_START32 = _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned int),
  496. };
  497. static long audio_effects_compat_ioctl(struct file *file, unsigned int cmd,
  498. unsigned long arg)
  499. {
  500. struct q6audio_effects *effects = file->private_data;
  501. int rc = 0, i;
  502. switch (cmd) {
  503. case AUDIO_SET_EFFECTS_CONFIG32: {
  504. struct msm_hwacc_effects_config32 config32;
  505. struct msm_hwacc_effects_config *config = &effects->config;
  506. mutex_lock(&effects->lock);
  507. memset(&effects->config, 0, sizeof(effects->config));
  508. if (copy_from_user(&config32, (void *)arg,
  509. sizeof(config32))) {
  510. pr_err("%s: copy to user for AUDIO_SET_EFFECTS_CONFIG failed\n",
  511. __func__);
  512. rc = -EFAULT;
  513. mutex_unlock(&effects->lock);
  514. break;
  515. }
  516. config->input.buf_size = config32.input.buf_size;
  517. config->input.num_buf = config32.input.num_buf;
  518. config->input.num_channels = config32.input.num_channels;
  519. config->input.sample_rate = config32.input.sample_rate;
  520. config->input.bits_per_sample = config32.input.bits_per_sample;
  521. config->input.buf_size = config32.input.buf_size;
  522. for (i = 0; i < MAX_CHANNELS_SUPPORTED; i++)
  523. config->input.channel_map[i] =
  524. config32.input.channel_map[i];
  525. config->output.buf_size = config32.output.buf_size;
  526. config->output.num_buf = config32.output.num_buf;
  527. config->output.num_channels = config32.output.num_channels;
  528. config->output.sample_rate = config32.output.sample_rate;
  529. config->output.bits_per_sample =
  530. config32.output.bits_per_sample;
  531. config->output.buf_size = config32.output.buf_size;
  532. for (i = 0; i < MAX_CHANNELS_SUPPORTED; i++)
  533. config->output.channel_map[i] =
  534. config32.output.channel_map[i];
  535. config->buf_cfg.input_len = config32.buf_cfg.input_len;
  536. config->buf_cfg.output_len = config32.buf_cfg.output_len;
  537. config->meta_mode_enabled = config32.meta_mode_enabled;
  538. config->overwrite_topology = config32.overwrite_topology;
  539. config->topology = config32.topology;
  540. pr_debug("%s: write buf_size: %d, num_buf: %d, sample_rate: %d, channels: %d\n",
  541. __func__, effects->config.output.buf_size,
  542. effects->config.output.num_buf,
  543. effects->config.output.sample_rate,
  544. effects->config.output.num_channels);
  545. pr_debug("%s: read buf_size: %d, num_buf: %d, sample_rate: %d, channels: %d\n",
  546. __func__, effects->config.input.buf_size,
  547. effects->config.input.num_buf,
  548. effects->config.input.sample_rate,
  549. effects->config.input.num_channels);
  550. mutex_unlock(&effects->lock);
  551. break;
  552. }
  553. case AUDIO_EFFECTS_SET_BUF_LEN32: {
  554. struct msm_hwacc_buf_cfg32 buf_cfg32;
  555. struct msm_hwacc_effects_config *config = &effects->config;
  556. mutex_lock(&effects->lock);
  557. if (copy_from_user(&buf_cfg32, (void *)arg,
  558. sizeof(buf_cfg32))) {
  559. pr_err("%s: copy from user for AUDIO_EFFECTS_SET_BUF_LEN failed\n",
  560. __func__);
  561. rc = -EFAULT;
  562. mutex_unlock(&effects->lock);
  563. break;
  564. }
  565. config->buf_cfg.input_len = buf_cfg32.input_len;
  566. config->buf_cfg.output_len = buf_cfg32.output_len;
  567. pr_debug("%s: write buf len: %d, read buf len: %d\n",
  568. __func__, effects->config.buf_cfg.output_len,
  569. effects->config.buf_cfg.input_len);
  570. mutex_unlock(&effects->lock);
  571. break;
  572. }
  573. case AUDIO_EFFECTS_GET_BUF_AVAIL32: {
  574. struct msm_hwacc_buf_avail32 buf_avail;
  575. memset(&buf_avail, 0, sizeof(buf_avail));
  576. mutex_lock(&effects->lock);
  577. buf_avail.input_num_avail = atomic_read(&effects->in_count);
  578. buf_avail.output_num_avail = atomic_read(&effects->out_count);
  579. pr_debug("%s: write buf avail: %d, read buf avail: %d\n",
  580. __func__, buf_avail.output_num_avail,
  581. buf_avail.input_num_avail);
  582. if (copy_to_user((void *)arg, &buf_avail,
  583. sizeof(buf_avail))) {
  584. pr_err("%s: copy to user for AUDIO_EFFECTS_GET_NUM_BUF_AVAIL failed\n",
  585. __func__);
  586. rc = -EFAULT;
  587. }
  588. mutex_unlock(&effects->lock);
  589. break;
  590. }
  591. case AUDIO_EFFECTS_SET_PP_PARAMS32: {
  592. long argvalues[MAX_PP_PARAMS_SZ] = {0};
  593. int argvalues32[MAX_PP_PARAMS_SZ] = {0};
  594. mutex_lock(&effects->lock);
  595. if (copy_from_user(argvalues32, (void *)arg,
  596. MAX_PP_PARAMS_SZ*sizeof(int))) {
  597. pr_err("%s: copy from user failed for pp params\n",
  598. __func__);
  599. mutex_unlock(&effects->lock);
  600. return -EFAULT;
  601. }
  602. for (i = 0; i < MAX_PP_PARAMS_SZ; i++)
  603. argvalues[i] = argvalues32[i];
  604. rc = audio_effects_set_pp_param(effects, argvalues);
  605. mutex_unlock(&effects->lock);
  606. break;
  607. }
  608. case AUDIO_START32: {
  609. rc = audio_effects_shared_ioctl(file, AUDIO_START, arg);
  610. break;
  611. }
  612. case AUDIO_EFFECTS_WRITE32: {
  613. rc = audio_effects_shared_ioctl(file, AUDIO_EFFECTS_WRITE, arg);
  614. break;
  615. }
  616. case AUDIO_EFFECTS_READ32: {
  617. rc = audio_effects_shared_ioctl(file, AUDIO_EFFECTS_READ, arg);
  618. break;
  619. }
  620. default:
  621. pr_debug("%s: unhandled ioctl\n", __func__);
  622. rc = -EINVAL;
  623. break;
  624. }
  625. return rc;
  626. }
  627. #endif
  628. static int audio_effects_release(struct inode *inode, struct file *file)
  629. {
  630. struct q6audio_effects *effects = file->private_data;
  631. int rc = 0;
  632. if (!effects) {
  633. pr_err("%s: effect is NULL\n", __func__);
  634. return -EINVAL;
  635. }
  636. if (effects->opened) {
  637. rc = wait_event_timeout(effects->write_wait,
  638. atomic_read(&effects->out_count),
  639. WAIT_TIMEDOUT_DURATION_SECS * HZ);
  640. if (!rc)
  641. pr_err("%s: write wait_event_timeout failed\n",
  642. __func__);
  643. rc = wait_event_timeout(effects->read_wait,
  644. atomic_read(&effects->in_count),
  645. WAIT_TIMEDOUT_DURATION_SECS * HZ);
  646. if (!rc)
  647. pr_err("%s: read wait_event_timeout failed\n",
  648. __func__);
  649. rc = q6asm_cmd(effects->ac, CMD_CLOSE);
  650. if (rc < 0)
  651. pr_err("%s[%pK]:Failed to close the session rc=%d\n",
  652. __func__, effects, rc);
  653. effects->opened = 0;
  654. effects->started = 0;
  655. audio_effects_deinit_pp(effects->ac);
  656. }
  657. if (effects->buf_alloc) {
  658. q6asm_audio_client_buf_free_contiguous(IN, effects->ac);
  659. q6asm_audio_client_buf_free_contiguous(OUT, effects->ac);
  660. }
  661. q6asm_audio_client_free(effects->ac);
  662. mutex_destroy(&effects->lock);
  663. kfree(effects);
  664. pr_debug("%s: close session success\n", __func__);
  665. return rc;
  666. }
  667. static int audio_effects_open(struct inode *inode, struct file *file)
  668. {
  669. struct q6audio_effects *effects;
  670. int rc = 0;
  671. effects = kzalloc(sizeof(struct q6audio_effects), GFP_KERNEL);
  672. if (!effects)
  673. return -ENOMEM;
  674. effects->ac = q6asm_audio_client_alloc(
  675. (app_cb)audio_effects_event_handler,
  676. (void *)effects);
  677. if (!effects->ac) {
  678. pr_err("%s: Could not allocate memory for audio client\n",
  679. __func__);
  680. kfree(effects);
  681. return -ENOMEM;
  682. }
  683. init_waitqueue_head(&effects->read_wait);
  684. init_waitqueue_head(&effects->write_wait);
  685. mutex_init(&effects->lock);
  686. effects->opened = 0;
  687. effects->started = 0;
  688. effects->buf_alloc = 0;
  689. file->private_data = effects;
  690. pr_debug("%s: open session success\n", __func__);
  691. return rc;
  692. }
  693. static const struct file_operations audio_effects_fops = {
  694. .owner = THIS_MODULE,
  695. .open = audio_effects_open,
  696. .release = audio_effects_release,
  697. .unlocked_ioctl = audio_effects_ioctl,
  698. #ifdef CONFIG_COMPAT
  699. .compat_ioctl = audio_effects_compat_ioctl,
  700. #endif
  701. };
  702. struct miscdevice audio_effects_misc = {
  703. .minor = MISC_DYNAMIC_MINOR,
  704. .name = "msm_hweffects",
  705. .fops = &audio_effects_fops,
  706. };
  707. int __init audio_effects_init(void)
  708. {
  709. return misc_register(&audio_effects_misc);
  710. }
  711. void audio_effects_exit(void)
  712. {
  713. misc_deregister(&audio_effects_misc);
  714. }
  715. MODULE_DESCRIPTION("Audio hardware accelerated effects driver");
  716. MODULE_LICENSE("GPL v2");