audio_multi_aac.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* aac audio output device
  3. *
  4. * Copyright (C) 2008 Google, Inc.
  5. * Copyright (C) 2008 HTC Corporation
  6. * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
  7. */
  8. #include <linux/msm_audio_aac.h>
  9. #include <linux/compat.h>
  10. #include <soc/qcom/socinfo.h>
  11. #include "audio_utils_aio.h"
  12. #define AUDIO_AAC_DUAL_MONO_INVALID -1
  13. /* Default number of pre-allocated event packets */
  14. #define PCM_BUFSZ_MIN_AACM ((8*1024) + sizeof(struct dec_meta_out))
  15. static struct miscdevice audio_multiaac_misc;
  16. static struct ws_mgr audio_multiaac_ws_mgr;
  17. #ifdef CONFIG_DEBUG_FS
  18. static const struct file_operations audio_aac_debug_fops = {
  19. .read = audio_aio_debug_read,
  20. .open = audio_aio_debug_open,
  21. };
  22. #endif
  23. static long audio_ioctl_shared(struct file *file, unsigned int cmd,
  24. void *arg)
  25. {
  26. struct q6audio_aio *audio = file->private_data;
  27. int rc = 0;
  28. switch (cmd) {
  29. case AUDIO_START: {
  30. struct asm_aac_cfg aac_cfg;
  31. struct msm_audio_aac_config *aac_config;
  32. uint32_t sbr_ps = 0x00;
  33. aac_config = (struct msm_audio_aac_config *)audio->codec_cfg;
  34. if (audio->feedback == TUNNEL_MODE) {
  35. aac_cfg.sample_rate = aac_config->sample_rate;
  36. aac_cfg.ch_cfg = aac_config->channel_configuration;
  37. } else {
  38. aac_cfg.sample_rate = audio->pcm_cfg.sample_rate;
  39. aac_cfg.ch_cfg = audio->pcm_cfg.channel_count;
  40. }
  41. pr_debug("%s: AUDIO_START session_id[%d]\n", __func__,
  42. audio->ac->session);
  43. if (audio->feedback == NON_TUNNEL_MODE) {
  44. /* Configure PCM output block */
  45. rc = q6asm_enc_cfg_blk_pcm_native(audio->ac,
  46. audio->pcm_cfg.sample_rate,
  47. audio->pcm_cfg.channel_count);
  48. if (rc < 0) {
  49. pr_err("pcm output block config failed\n");
  50. break;
  51. }
  52. }
  53. /* turn on both sbr and ps */
  54. rc = q6asm_enable_sbrps(audio->ac, sbr_ps);
  55. if (rc < 0)
  56. pr_err("sbr-ps enable failed\n");
  57. if (aac_config->sbr_ps_on_flag)
  58. aac_cfg.aot = AAC_ENC_MODE_EAAC_P;
  59. else if (aac_config->sbr_on_flag)
  60. aac_cfg.aot = AAC_ENC_MODE_AAC_P;
  61. else
  62. aac_cfg.aot = AAC_ENC_MODE_AAC_LC;
  63. switch (aac_config->format) {
  64. case AUDIO_AAC_FORMAT_ADTS:
  65. aac_cfg.format = 0x00;
  66. break;
  67. case AUDIO_AAC_FORMAT_LOAS:
  68. aac_cfg.format = 0x01;
  69. break;
  70. case AUDIO_AAC_FORMAT_ADIF:
  71. aac_cfg.format = 0x02;
  72. break;
  73. default:
  74. case AUDIO_AAC_FORMAT_RAW:
  75. aac_cfg.format = 0x03;
  76. }
  77. aac_cfg.ep_config = aac_config->ep_config;
  78. aac_cfg.section_data_resilience =
  79. aac_config->aac_section_data_resilience_flag;
  80. aac_cfg.scalefactor_data_resilience =
  81. aac_config->aac_scalefactor_data_resilience_flag;
  82. aac_cfg.spectral_data_resilience =
  83. aac_config->aac_spectral_data_resilience_flag;
  84. pr_debug("%s:format=%x aot=%d ch=%d sr=%d\n",
  85. __func__, aac_cfg.format,
  86. aac_cfg.aot, aac_cfg.ch_cfg,
  87. aac_cfg.sample_rate);
  88. /* Configure Media format block */
  89. rc = q6asm_media_format_block_multi_aac(audio->ac, &aac_cfg);
  90. if (rc < 0) {
  91. pr_err("cmd media format block failed\n");
  92. break;
  93. }
  94. /* Fall back to the default number of channels
  95. * if aac_cfg.ch_cfg is not between 1-6
  96. */
  97. if ((aac_cfg.ch_cfg == 0) || (aac_cfg.ch_cfg > 6))
  98. aac_cfg.ch_cfg = 2;
  99. rc = q6asm_set_encdec_chan_map(audio->ac, aac_cfg.ch_cfg);
  100. if (rc < 0) {
  101. pr_err("%s: cmd set encdec_chan_map failed\n",
  102. __func__);
  103. break;
  104. }
  105. rc = audio_aio_enable(audio);
  106. audio->eos_rsp = 0;
  107. audio->eos_flag = 0;
  108. if (!rc) {
  109. audio->enabled = 1;
  110. } else {
  111. audio->enabled = 0;
  112. pr_err("Audio Start procedure failed rc=%d\n", rc);
  113. break;
  114. }
  115. pr_info("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__,
  116. audio->ac->session,
  117. audio->enabled);
  118. if (audio->stopped == 1)
  119. audio->stopped = 0;
  120. break;
  121. }
  122. case AUDIO_SET_AAC_CONFIG: {
  123. struct msm_audio_aac_config *aac_config;
  124. uint16_t sce_left = 1, sce_right = 2;
  125. if (arg == NULL) {
  126. pr_err("%s: NULL config pointer\n", __func__);
  127. rc = -EINVAL;
  128. break;
  129. }
  130. memcpy(audio->codec_cfg, arg,
  131. sizeof(struct msm_audio_aac_config));
  132. aac_config = audio->codec_cfg;
  133. if (aac_config->dual_mono_mode >
  134. AUDIO_AAC_DUAL_MONO_PL_SR) {
  135. pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid dual_mono mode =%d\n",
  136. __func__, aac_config->dual_mono_mode);
  137. } else {
  138. /* convert the data from user into sce_left
  139. * and sce_right based on the definitions
  140. */
  141. pr_debug("%s: AUDIO_SET_AAC_CONFIG: modify dual_mono mode =%d\n",
  142. __func__, aac_config->dual_mono_mode);
  143. switch (aac_config->dual_mono_mode) {
  144. case AUDIO_AAC_DUAL_MONO_PL_PR:
  145. sce_left = 1;
  146. sce_right = 1;
  147. break;
  148. case AUDIO_AAC_DUAL_MONO_SL_SR:
  149. sce_left = 2;
  150. sce_right = 2;
  151. break;
  152. case AUDIO_AAC_DUAL_MONO_SL_PR:
  153. sce_left = 2;
  154. sce_right = 1;
  155. break;
  156. case AUDIO_AAC_DUAL_MONO_PL_SR:
  157. default:
  158. sce_left = 1;
  159. sce_right = 2;
  160. break;
  161. }
  162. rc = q6asm_cfg_dual_mono_aac(audio->ac,
  163. sce_left, sce_right);
  164. if (rc < 0)
  165. pr_err("%s: asm cmd dualmono failed rc=%d\n",
  166. __func__, rc);
  167. } break;
  168. break;
  169. }
  170. case AUDIO_SET_AAC_MIX_CONFIG: {
  171. u32 *mix_coeff = (u32 *)arg;
  172. if (!arg) {
  173. pr_err("%s: Invalid param for %s\n",
  174. __func__, "AUDIO_SET_AAC_MIX_CONFIG");
  175. rc = -EINVAL;
  176. break;
  177. }
  178. pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG", __func__);
  179. pr_debug("%s, value of coeff = %d",
  180. __func__, *mix_coeff);
  181. q6asm_cfg_aac_sel_mix_coef(audio->ac, *mix_coeff);
  182. if (rc < 0)
  183. pr_err("%s asm aac_sel_mix_coef failed rc=%d\n",
  184. __func__, rc);
  185. break;
  186. }
  187. default:
  188. pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
  189. rc = -EINVAL;
  190. break;
  191. }
  192. return rc;
  193. }
  194. static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  195. {
  196. struct q6audio_aio *audio = file->private_data;
  197. int rc = 0;
  198. switch (cmd) {
  199. case AUDIO_START: {
  200. rc = audio_ioctl_shared(file, cmd, (void *)arg);
  201. break;
  202. }
  203. case AUDIO_GET_AAC_CONFIG: {
  204. if (copy_to_user((void *)arg, audio->codec_cfg,
  205. sizeof(struct msm_audio_aac_config))) {
  206. pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG failed\n"
  207. , __func__);
  208. rc = -EFAULT;
  209. break;
  210. }
  211. break;
  212. }
  213. case AUDIO_SET_AAC_CONFIG: {
  214. struct msm_audio_aac_config aac_config;
  215. if (copy_from_user(&aac_config, (void *)arg,
  216. sizeof(aac_config))) {
  217. pr_err("%s: copy_from_user for AUDIO_SET_AAC_CONFIG failed\n"
  218. , __func__);
  219. rc = -EFAULT;
  220. }
  221. rc = audio_ioctl_shared(file, cmd, &aac_config);
  222. if (rc)
  223. pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n",
  224. __func__, rc);
  225. break;
  226. }
  227. case AUDIO_SET_AAC_MIX_CONFIG: {
  228. u32 mix_config;
  229. pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG", __func__);
  230. if (copy_from_user(&mix_config, (void *)arg,
  231. sizeof(u32))) {
  232. pr_err("%s: copy_from_user for AUDIO_SET_AAC_MIX_CONFIG failed\n",
  233. __func__);
  234. rc = -EFAULT;
  235. break;
  236. }
  237. rc = audio_ioctl_shared(file, cmd, &mix_config);
  238. if (rc)
  239. pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n",
  240. __func__, rc);
  241. break;
  242. }
  243. default: {
  244. pr_debug("Calling utils ioctl\n");
  245. rc = audio->codec_ioctl(file, cmd, arg);
  246. }
  247. }
  248. return rc;
  249. }
  250. #ifdef CONFIG_COMPAT
  251. struct msm_audio_aac_config32 {
  252. s16 format;
  253. u16 audio_object;
  254. u16 ep_config; /* 0 ~ 3 useful only obj = ERLC */
  255. u16 aac_section_data_resilience_flag;
  256. u16 aac_scalefactor_data_resilience_flag;
  257. u16 aac_spectral_data_resilience_flag;
  258. u16 sbr_on_flag;
  259. u16 sbr_ps_on_flag;
  260. u16 dual_mono_mode;
  261. u16 channel_configuration;
  262. u16 sample_rate;
  263. };
  264. enum {
  265. AUDIO_SET_AAC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC,
  266. (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_aac_config32),
  267. AUDIO_GET_AAC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC,
  268. (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_aac_config32),
  269. };
  270. static long audio_compat_ioctl(struct file *file, unsigned int cmd,
  271. unsigned long arg)
  272. {
  273. struct q6audio_aio *audio = file->private_data;
  274. int rc = 0;
  275. switch (cmd) {
  276. case AUDIO_START: {
  277. rc = audio_ioctl_shared(file, cmd, (void *)arg);
  278. break;
  279. }
  280. case AUDIO_GET_AAC_CONFIG_32: {
  281. struct msm_audio_aac_config *aac_config;
  282. struct msm_audio_aac_config32 aac_config_32;
  283. memset(&aac_config_32, 0, sizeof(aac_config_32));
  284. aac_config = (struct msm_audio_aac_config *)audio->codec_cfg;
  285. aac_config_32.format = aac_config->format;
  286. aac_config_32.audio_object = aac_config->audio_object;
  287. aac_config_32.ep_config = aac_config->ep_config;
  288. aac_config_32.aac_section_data_resilience_flag =
  289. aac_config->aac_section_data_resilience_flag;
  290. aac_config_32.aac_scalefactor_data_resilience_flag =
  291. aac_config->aac_scalefactor_data_resilience_flag;
  292. aac_config_32.aac_spectral_data_resilience_flag =
  293. aac_config->aac_spectral_data_resilience_flag;
  294. aac_config_32.sbr_on_flag = aac_config->sbr_on_flag;
  295. aac_config_32.sbr_ps_on_flag = aac_config->sbr_ps_on_flag;
  296. aac_config_32.dual_mono_mode = aac_config->dual_mono_mode;
  297. aac_config_32.channel_configuration =
  298. aac_config->channel_configuration;
  299. aac_config_32.sample_rate = aac_config->sample_rate;
  300. if (copy_to_user((void *)arg, &aac_config_32,
  301. sizeof(aac_config_32))) {
  302. pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG_32 failed\n",
  303. __func__);
  304. rc = -EFAULT;
  305. break;
  306. }
  307. break;
  308. }
  309. case AUDIO_SET_AAC_CONFIG_32: {
  310. struct msm_audio_aac_config aac_config;
  311. struct msm_audio_aac_config32 aac_config_32;
  312. pr_debug("%s: AUDIO_SET_AAC_CONFIG\n", __func__);
  313. if (copy_from_user(&aac_config_32, (void *)arg,
  314. sizeof(aac_config_32))) {
  315. pr_err(
  316. "%s: copy_from_user for AUDIO_SET_AAC_CONFIG_32 failed",
  317. __func__);
  318. rc = -EFAULT;
  319. break;
  320. }
  321. aac_config.format = aac_config_32.format;
  322. aac_config.audio_object = aac_config_32.audio_object;
  323. aac_config.ep_config = aac_config_32.ep_config;
  324. aac_config.aac_section_data_resilience_flag =
  325. aac_config_32.aac_section_data_resilience_flag;
  326. aac_config.aac_scalefactor_data_resilience_flag =
  327. aac_config_32.aac_scalefactor_data_resilience_flag;
  328. aac_config.aac_spectral_data_resilience_flag =
  329. aac_config_32.aac_spectral_data_resilience_flag;
  330. aac_config.sbr_on_flag = aac_config_32.sbr_on_flag;
  331. aac_config.sbr_ps_on_flag = aac_config_32.sbr_ps_on_flag;
  332. aac_config.dual_mono_mode = aac_config_32.dual_mono_mode;
  333. aac_config.channel_configuration =
  334. aac_config_32.channel_configuration;
  335. aac_config.sample_rate = aac_config_32.sample_rate;
  336. cmd = AUDIO_SET_AAC_CONFIG;
  337. rc = audio_ioctl_shared(file, cmd, &aac_config);
  338. if (rc)
  339. pr_err("%s:AUDIO_SET_AAC_CONFIG failed. rc= %d\n",
  340. __func__, rc);
  341. break;
  342. }
  343. case AUDIO_SET_AAC_MIX_CONFIG: {
  344. u32 mix_config;
  345. pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG\n", __func__);
  346. if (copy_from_user(&mix_config, (void *)arg,
  347. sizeof(u32))) {
  348. pr_err("%s: copy_from_user for AUDIO_SET_AAC_MIX_CONFIG failed\n"
  349. , __func__);
  350. rc = -EFAULT;
  351. break;
  352. }
  353. rc = audio_ioctl_shared(file, cmd, &mix_config);
  354. if (rc)
  355. pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n",
  356. __func__, rc);
  357. break;
  358. }
  359. default: {
  360. pr_debug("Calling utils ioctl\n");
  361. rc = audio->codec_compat_ioctl(file, cmd, arg);
  362. }
  363. }
  364. return rc;
  365. }
  366. #else
  367. #define audio_compat_ioctl NULL
  368. #endif
  369. static int audio_open(struct inode *inode, struct file *file)
  370. {
  371. struct q6audio_aio *audio = NULL;
  372. int rc = 0;
  373. struct msm_audio_aac_config *aac_config = NULL;
  374. #ifdef CONFIG_DEBUG_FS
  375. /* 4 bytes represents decoder number, 1 byte for terminate string */
  376. char name[sizeof "msm_multi_aac_" + 5];
  377. #endif
  378. audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL);
  379. if (audio == NULL)
  380. return -ENOMEM;
  381. audio->codec_cfg = kzalloc(sizeof(struct msm_audio_aac_config),
  382. GFP_KERNEL);
  383. if (audio->codec_cfg == NULL) {
  384. kfree(audio);
  385. return -ENOMEM;
  386. }
  387. aac_config = audio->codec_cfg;
  388. audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN_AACM;
  389. audio->miscdevice = &audio_multiaac_misc;
  390. audio->wakelock_voted = false;
  391. audio->audio_ws_mgr = &audio_multiaac_ws_mgr;
  392. aac_config->dual_mono_mode = AUDIO_AAC_DUAL_MONO_INVALID;
  393. audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb,
  394. (void *)audio);
  395. if (!audio->ac) {
  396. pr_err("Could not allocate memory for audio client\n");
  397. kfree(audio->codec_cfg);
  398. kfree(audio);
  399. return -ENOMEM;
  400. }
  401. rc = audio_aio_open(audio, file);
  402. if (rc < 0) {
  403. pr_err("%s: audio_aio_open rc=%d\n",
  404. __func__, rc);
  405. goto fail;
  406. }
  407. /* open in T/NT mode */
  408. if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) {
  409. rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM,
  410. FORMAT_MPEG4_MULTI_AAC);
  411. if (rc < 0) {
  412. pr_err("NT mode Open failed rc=%d\n", rc);
  413. rc = -ENODEV;
  414. goto fail;
  415. }
  416. audio->feedback = NON_TUNNEL_MODE;
  417. /* open AAC decoder, expected frames is always 1
  418. * audio->buf_cfg.frames_per_buf = 0x01;
  419. */
  420. audio->buf_cfg.meta_info_enable = 0x01;
  421. } else if ((file->f_mode & FMODE_WRITE) &&
  422. !(file->f_mode & FMODE_READ)) {
  423. rc = q6asm_open_write(audio->ac, FORMAT_MPEG4_MULTI_AAC);
  424. if (rc < 0) {
  425. pr_err("T mode Open failed rc=%d\n", rc);
  426. rc = -ENODEV;
  427. goto fail;
  428. }
  429. audio->feedback = TUNNEL_MODE;
  430. audio->buf_cfg.meta_info_enable = 0x00;
  431. } else {
  432. pr_err("Not supported mode\n");
  433. rc = -EACCES;
  434. goto fail;
  435. }
  436. #ifdef CONFIG_DEBUG_FS
  437. snprintf(name, sizeof(name), "msm_multi_aac_%04x", audio->ac->session);
  438. audio->dentry = debugfs_create_file(name, S_IFREG | 0444,
  439. NULL, (void *)audio,
  440. &audio_aac_debug_fops);
  441. if (IS_ERR(audio->dentry))
  442. pr_debug("debugfs_create_file failed\n");
  443. #endif
  444. pr_info("%s:AAC 5.1 Decoder OPEN success mode[%d]session[%d]\n",
  445. __func__, audio->feedback, audio->ac->session);
  446. return rc;
  447. fail:
  448. q6asm_audio_client_free(audio->ac);
  449. kfree(audio->codec_cfg);
  450. kfree(audio);
  451. return rc;
  452. }
  453. static const struct file_operations audio_aac_fops = {
  454. .owner = THIS_MODULE,
  455. .open = audio_open,
  456. .release = audio_aio_release,
  457. .unlocked_ioctl = audio_ioctl,
  458. .fsync = audio_aio_fsync,
  459. .compat_ioctl = audio_compat_ioctl
  460. };
  461. static struct miscdevice audio_multiaac_misc = {
  462. .minor = MISC_DYNAMIC_MINOR,
  463. .name = "msm_multi_aac",
  464. .fops = &audio_aac_fops,
  465. };
  466. int __init audio_multiaac_init(void)
  467. {
  468. int ret = misc_register(&audio_multiaac_misc);
  469. if (ret == 0)
  470. device_init_wakeup(audio_multiaac_misc.this_device, true);
  471. audio_multiaac_ws_mgr.ref_cnt = 0;
  472. mutex_init(&audio_multiaac_ws_mgr.ws_lock);
  473. return ret;
  474. }
  475. void audio_multiaac_exit(void)
  476. {
  477. mutex_destroy(&audio_multiaac_ws_mgr.ws_lock);
  478. misc_deregister(&audio_multiaac_misc);
  479. }