audio_hwacc_effects.c 21 KB

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