msm-dolby-dap-config.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. /* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License version 2 and
  4. * only version 2 as published by the Free Software Foundation.
  5. *
  6. * This program is distributed in the hope that it will be useful,
  7. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. * GNU General Public License for more details.
  10. */
  11. #include <linux/init.h>
  12. #include <linux/err.h>
  13. #include <linux/module.h>
  14. #include <linux/moduleparam.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/bitops.h>
  17. #include <linux/mutex.h>
  18. #include <linux/of_device.h>
  19. #include <linux/slab.h>
  20. #include <sound/core.h>
  21. #include <sound/soc.h>
  22. #include <sound/soc-dapm.h>
  23. #include <sound/pcm.h>
  24. #include <sound/initval.h>
  25. #include <sound/control.h>
  26. #include <sound/q6adm-v2.h>
  27. #include <sound/q6asm-v2.h>
  28. #include <sound/q6afe-v2.h>
  29. #include "msm-dolby-dap-config.h"
  30. #ifndef DOLBY_PARAM_VCNB_MAX_LENGTH
  31. #define DOLBY_PARAM_VCNB_MAX_LENGTH 40
  32. #endif
  33. /* dolby endp based parameters */
  34. struct dolby_dap_endp_params_s {
  35. int device;
  36. int device_ch_caps;
  37. int dap_device;
  38. int params_id[DOLBY_NUM_ENDP_DEPENDENT_PARAMS];
  39. int params_len[DOLBY_NUM_ENDP_DEPENDENT_PARAMS];
  40. int params_offset[DOLBY_NUM_ENDP_DEPENDENT_PARAMS];
  41. int params_val[DOLBY_ENDDEP_PARAM_LENGTH];
  42. };
  43. const struct dolby_dap_endp_params_s
  44. dolby_dap_endp_params[NUM_DOLBY_ENDP_DEVICE] = {
  45. {EARPIECE, 2, DOLBY_ENDP_EXT_SPEAKERS,
  46. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  47. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  48. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  49. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  50. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  51. {-320, -320, 144}
  52. },
  53. {SPEAKER, 2, DOLBY_ENDP_INT_SPEAKERS,
  54. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  55. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  56. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  57. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  58. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  59. {-320, -320, 144}
  60. },
  61. {WIRED_HEADSET, 2, DOLBY_ENDP_HEADPHONES,
  62. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  63. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  64. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  65. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  66. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  67. {-320, -320, 144}
  68. },
  69. {WIRED_HEADPHONE, 2, DOLBY_ENDP_HEADPHONES,
  70. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  71. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  72. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  73. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  74. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  75. {-320, -320, 144}
  76. },
  77. {BLUETOOTH_SCO, 2, DOLBY_ENDP_EXT_SPEAKERS,
  78. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  79. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  80. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  81. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  82. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  83. {-320, -320, 144}
  84. },
  85. {BLUETOOTH_SCO_HEADSET, 2, DOLBY_ENDP_EXT_SPEAKERS,
  86. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  87. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  88. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  89. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  90. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  91. {-320, -320, 144}
  92. },
  93. {BLUETOOTH_SCO_CARKIT, 2, DOLBY_ENDP_EXT_SPEAKERS,
  94. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  95. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  96. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  97. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  98. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  99. {-320, -320, 144}
  100. },
  101. {BLUETOOTH_A2DP, 2, DOLBY_ENDP_EXT_SPEAKERS,
  102. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  103. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  104. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  105. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  106. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  107. {-320, -320, 144}
  108. },
  109. {BLUETOOTH_A2DP_HEADPHONES, 2, DOLBY_ENDP_HEADPHONES,
  110. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  111. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  112. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  113. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  114. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  115. {-320, -320, 144}
  116. },
  117. {BLUETOOTH_A2DP_SPEAKER, 2, DOLBY_ENDP_EXT_SPEAKERS,
  118. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  119. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  120. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  121. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  122. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  123. {-320, -320, 144}
  124. },
  125. {AUX_DIGITAL, 2, DOLBY_ENDP_HDMI,
  126. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  127. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  128. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  129. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  130. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  131. {-496, -496, 0}
  132. },
  133. {AUX_DIGITAL, 6, DOLBY_ENDP_HDMI,
  134. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  135. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  136. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  137. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  138. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  139. {-496, -496, 0}
  140. },
  141. {AUX_DIGITAL, 8, DOLBY_ENDP_HDMI,
  142. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  143. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  144. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  145. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  146. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  147. {-496, -496, 0}
  148. },
  149. {ANLG_DOCK_HEADSET, 2, DOLBY_ENDP_HEADPHONES,
  150. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  151. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  152. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  153. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  154. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  155. {-320, -320, 144}
  156. },
  157. {DGTL_DOCK_HEADSET, 2, DOLBY_ENDP_HEADPHONES,
  158. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  159. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  160. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  161. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  162. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  163. {-320, -320, 144}
  164. },
  165. {USB_ACCESSORY, 2, DOLBY_ENDP_EXT_SPEAKERS,
  166. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  167. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  168. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  169. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  170. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  171. {-320, -320, 144}
  172. },
  173. {USB_DEVICE, 2, DOLBY_ENDP_EXT_SPEAKERS,
  174. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  175. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  176. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  177. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  178. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  179. {-320, -320, 144}
  180. },
  181. {REMOTE_SUBMIX, 2, DOLBY_ENDP_HDMI,
  182. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  183. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  184. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  185. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  186. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  187. {-496, -496, 0}
  188. },
  189. {ANC_HEADSET, 2, DOLBY_ENDP_HEADPHONES,
  190. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  191. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  192. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  193. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  194. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  195. {-320, -320, 144}
  196. },
  197. {ANC_HEADPHONE, 2, DOLBY_ENDP_HEADPHONES,
  198. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  199. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  200. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  201. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  202. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  203. {-320, -320, 144}
  204. },
  205. {PROXY, 2, DOLBY_ENDP_EXT_SPEAKERS,
  206. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  207. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  208. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  209. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  210. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  211. {-320, -320, 144}
  212. },
  213. {PROXY, 6, DOLBY_ENDP_EXT_SPEAKERS,
  214. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  215. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  216. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  217. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  218. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  219. {-320, -320, 144}
  220. },
  221. {FM, 2, DOLBY_ENDP_HDMI,
  222. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  223. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  224. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  225. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  226. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  227. {-496, -496, 0}
  228. },
  229. {FM_TX, 2, DOLBY_ENDP_EXT_SPEAKERS,
  230. {DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_VMB},
  231. {DOLBY_ENDDEP_PARAM_DVLO_LENGTH, DOLBY_ENDDEP_PARAM_DVLI_LENGTH,
  232. DOLBY_ENDDEP_PARAM_VMB_LENGTH},
  233. {DOLBY_ENDDEP_PARAM_DVLO_OFFSET, DOLBY_ENDDEP_PARAM_DVLI_OFFSET,
  234. DOLBY_ENDDEP_PARAM_VMB_OFFSET},
  235. {-320, -320, 144}
  236. },
  237. };
  238. /* dolby param ids to/from dsp */
  239. static uint32_t dolby_dap_params_id[ALL_DOLBY_PARAMS] = {
  240. DOLBY_PARAM_ID_VDHE, DOLBY_PARAM_ID_VSPE, DOLBY_PARAM_ID_DSSF,
  241. DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLE,
  242. DOLBY_PARAM_ID_DVMC, DOLBY_PARAM_ID_DVME, DOLBY_PARAM_ID_IENB,
  243. DOLBY_PARAM_ID_IEBF, DOLBY_PARAM_ID_IEON, DOLBY_PARAM_ID_DEON,
  244. DOLBY_PARAM_ID_NGON, DOLBY_PARAM_ID_GEON, DOLBY_PARAM_ID_GENB,
  245. DOLBY_PARAM_ID_GEBF, DOLBY_PARAM_ID_AONB, DOLBY_PARAM_ID_AOBF,
  246. DOLBY_PARAM_ID_AOBG, DOLBY_PARAM_ID_AOON, DOLBY_PARAM_ID_ARNB,
  247. DOLBY_PARAM_ID_ARBF, DOLBY_PARAM_ID_PLB, DOLBY_PARAM_ID_PLMD,
  248. DOLBY_PARAM_ID_DHSB, DOLBY_PARAM_ID_DHRG, DOLBY_PARAM_ID_DSSB,
  249. DOLBY_PARAM_ID_DSSA, DOLBY_PARAM_ID_DVLA, DOLBY_PARAM_ID_IEBT,
  250. DOLBY_PARAM_ID_IEA, DOLBY_PARAM_ID_DEA, DOLBY_PARAM_ID_DED,
  251. DOLBY_PARAM_ID_GEBG, DOLBY_PARAM_ID_AOCC, DOLBY_PARAM_ID_ARBI,
  252. DOLBY_PARAM_ID_ARBL, DOLBY_PARAM_ID_ARBH, DOLBY_PARAM_ID_AROD,
  253. DOLBY_PARAM_ID_ARTP, DOLBY_PARAM_ID_VMON, DOLBY_PARAM_ID_VMB,
  254. DOLBY_PARAM_ID_VCNB, DOLBY_PARAM_ID_VCBF, DOLBY_PARAM_ID_PREG,
  255. DOLBY_PARAM_ID_VEN, DOLBY_PARAM_ID_PSTG, DOLBY_COMMIT_ALL_TO_DSP,
  256. DOLBY_COMMIT_TO_DSP, DOLBY_USE_CACHE, DOLBY_AUTO_ENDP,
  257. DOLBY_AUTO_ENDDEP_PARAMS
  258. };
  259. /* modifed state: 0x00000000 - Not updated
  260. * > 0x00000000 && < 0x00010000
  261. * Updated and not commited to DSP
  262. * 0x00010001 - Updated and commited to DSP
  263. * > 0x00010001 - Modified the commited value
  264. */
  265. static int dolby_dap_params_modified[MAX_DOLBY_PARAMS] = { 0 };
  266. /* param offset */
  267. static uint32_t dolby_dap_params_offset[MAX_DOLBY_PARAMS] = {
  268. DOLBY_PARAM_VDHE_OFFSET, DOLBY_PARAM_VSPE_OFFSET,
  269. DOLBY_PARAM_DSSF_OFFSET, DOLBY_PARAM_DVLI_OFFSET,
  270. DOLBY_PARAM_DVLO_OFFSET, DOLBY_PARAM_DVLE_OFFSET,
  271. DOLBY_PARAM_DVMC_OFFSET, DOLBY_PARAM_DVME_OFFSET,
  272. DOLBY_PARAM_IENB_OFFSET, DOLBY_PARAM_IEBF_OFFSET,
  273. DOLBY_PARAM_IEON_OFFSET, DOLBY_PARAM_DEON_OFFSET,
  274. DOLBY_PARAM_NGON_OFFSET, DOLBY_PARAM_GEON_OFFSET,
  275. DOLBY_PARAM_GENB_OFFSET, DOLBY_PARAM_GEBF_OFFSET,
  276. DOLBY_PARAM_AONB_OFFSET, DOLBY_PARAM_AOBF_OFFSET,
  277. DOLBY_PARAM_AOBG_OFFSET, DOLBY_PARAM_AOON_OFFSET,
  278. DOLBY_PARAM_ARNB_OFFSET, DOLBY_PARAM_ARBF_OFFSET,
  279. DOLBY_PARAM_PLB_OFFSET, DOLBY_PARAM_PLMD_OFFSET,
  280. DOLBY_PARAM_DHSB_OFFSET, DOLBY_PARAM_DHRG_OFFSET,
  281. DOLBY_PARAM_DSSB_OFFSET, DOLBY_PARAM_DSSA_OFFSET,
  282. DOLBY_PARAM_DVLA_OFFSET, DOLBY_PARAM_IEBT_OFFSET,
  283. DOLBY_PARAM_IEA_OFFSET, DOLBY_PARAM_DEA_OFFSET,
  284. DOLBY_PARAM_DED_OFFSET, DOLBY_PARAM_GEBG_OFFSET,
  285. DOLBY_PARAM_AOCC_OFFSET, DOLBY_PARAM_ARBI_OFFSET,
  286. DOLBY_PARAM_ARBL_OFFSET, DOLBY_PARAM_ARBH_OFFSET,
  287. DOLBY_PARAM_AROD_OFFSET, DOLBY_PARAM_ARTP_OFFSET,
  288. DOLBY_PARAM_VMON_OFFSET, DOLBY_PARAM_VMB_OFFSET,
  289. DOLBY_PARAM_VCNB_OFFSET, DOLBY_PARAM_VCBF_OFFSET,
  290. DOLBY_PARAM_PREG_OFFSET, DOLBY_PARAM_VEN_OFFSET,
  291. DOLBY_PARAM_PSTG_OFFSET
  292. };
  293. /* param_length */
  294. static uint32_t dolby_dap_params_length[MAX_DOLBY_PARAMS] = {
  295. DOLBY_PARAM_VDHE_LENGTH, DOLBY_PARAM_VSPE_LENGTH,
  296. DOLBY_PARAM_DSSF_LENGTH, DOLBY_PARAM_DVLI_LENGTH,
  297. DOLBY_PARAM_DVLO_LENGTH, DOLBY_PARAM_DVLE_LENGTH,
  298. DOLBY_PARAM_DVMC_LENGTH, DOLBY_PARAM_DVME_LENGTH,
  299. DOLBY_PARAM_IENB_LENGTH, DOLBY_PARAM_IEBF_LENGTH,
  300. DOLBY_PARAM_IEON_LENGTH, DOLBY_PARAM_DEON_LENGTH,
  301. DOLBY_PARAM_NGON_LENGTH, DOLBY_PARAM_GEON_LENGTH,
  302. DOLBY_PARAM_GENB_LENGTH, DOLBY_PARAM_GEBF_LENGTH,
  303. DOLBY_PARAM_AONB_LENGTH, DOLBY_PARAM_AOBF_LENGTH,
  304. DOLBY_PARAM_AOBG_LENGTH, DOLBY_PARAM_AOON_LENGTH,
  305. DOLBY_PARAM_ARNB_LENGTH, DOLBY_PARAM_ARBF_LENGTH,
  306. DOLBY_PARAM_PLB_LENGTH, DOLBY_PARAM_PLMD_LENGTH,
  307. DOLBY_PARAM_DHSB_LENGTH, DOLBY_PARAM_DHRG_LENGTH,
  308. DOLBY_PARAM_DSSB_LENGTH, DOLBY_PARAM_DSSA_LENGTH,
  309. DOLBY_PARAM_DVLA_LENGTH, DOLBY_PARAM_IEBT_LENGTH,
  310. DOLBY_PARAM_IEA_LENGTH, DOLBY_PARAM_DEA_LENGTH,
  311. DOLBY_PARAM_DED_LENGTH, DOLBY_PARAM_GEBG_LENGTH,
  312. DOLBY_PARAM_AOCC_LENGTH, DOLBY_PARAM_ARBI_LENGTH,
  313. DOLBY_PARAM_ARBL_LENGTH, DOLBY_PARAM_ARBH_LENGTH,
  314. DOLBY_PARAM_AROD_LENGTH, DOLBY_PARAM_ARTP_LENGTH,
  315. DOLBY_PARAM_VMON_LENGTH, DOLBY_PARAM_VMB_LENGTH,
  316. DOLBY_PARAM_VCNB_LENGTH, DOLBY_PARAM_VCBF_LENGTH,
  317. DOLBY_PARAM_PREG_LENGTH, DOLBY_PARAM_VEN_LENGTH,
  318. DOLBY_PARAM_PSTG_LENGTH
  319. };
  320. /* param_value */
  321. static uint32_t dolby_dap_params_value[TOTAL_LENGTH_DOLBY_PARAM] = {0};
  322. struct dolby_dap_params_get_s {
  323. int32_t port_id;
  324. uint32_t device_id;
  325. uint32_t param_id;
  326. uint32_t offset;
  327. uint32_t length;
  328. };
  329. struct dolby_dap_params_states_s {
  330. bool use_cache;
  331. bool auto_endp;
  332. bool enddep_params;
  333. int port_id;
  334. int port_open_count;
  335. int port_ids_dolby_can_be_enabled;
  336. int device;
  337. };
  338. static struct dolby_dap_params_get_s dolby_dap_params_get = {-1, DEVICE_OUT_ALL,
  339. 0, 0, 0};
  340. static struct dolby_dap_params_states_s dolby_dap_params_states = { true, true,
  341. true, DOLBY_INVALID_PORT_ID,
  342. 0, DEVICE_OUT_ALL, 0 };
  343. /*
  344. port_ids_dolby_can_be_enabled is set to 0x7FFFFFFF.
  345. this needs to be removed after interface validation
  346. */
  347. static int map_device_to_dolby_endpoint(int device)
  348. {
  349. int i, dolby_dap_device = DOLBY_ENDP_EXT_SPEAKERS;
  350. for (i = 0; i < NUM_DOLBY_ENDP_DEVICE; i++) {
  351. if (dolby_dap_endp_params[i].device == device) {
  352. dolby_dap_device = dolby_dap_endp_params[i].dap_device;
  353. break;
  354. }
  355. }
  356. /* default the endpoint to speaker if corresponding device entry */
  357. /* not found */
  358. if (i >= NUM_DOLBY_ENDP_DEVICE)
  359. dolby_dap_params_states.device = SPEAKER;
  360. return dolby_dap_device;
  361. }
  362. static int dolby_dap_send_end_point(int port_id)
  363. {
  364. int rc = 0;
  365. char *params_value;
  366. int *update_params_value;
  367. uint32_t params_length = (DOLBY_PARAM_INT_ENDP_LENGTH +
  368. DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t);
  369. pr_debug("%s\n", __func__);
  370. params_value = kzalloc(params_length, GFP_KERNEL);
  371. if (!params_value) {
  372. pr_err("%s, params memory alloc failed", __func__);
  373. return -ENOMEM;
  374. }
  375. update_params_value = (int *)params_value;
  376. *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
  377. *update_params_value++ = DOLBY_PARAM_ID_INIT_ENDP;
  378. *update_params_value++ = DOLBY_PARAM_INT_ENDP_LENGTH * sizeof(uint32_t);
  379. *update_params_value++ =
  380. map_device_to_dolby_endpoint(dolby_dap_params_states.device);
  381. rc = adm_dolby_dap_send_params(port_id, params_value, params_length);
  382. if (rc) {
  383. pr_err("%s: send dolby params failed\n", __func__);
  384. rc = -EINVAL;
  385. }
  386. kfree(params_value);
  387. return rc;
  388. }
  389. static int dolby_dap_send_enddep_params(int port_id, int device_channels)
  390. {
  391. int i, j, rc = 0, idx, offset;
  392. char *params_value;
  393. int *update_params_value;
  394. uint32_t params_length = (DOLBY_ENDDEP_PARAM_LENGTH +
  395. DOLBY_NUM_ENDP_DEPENDENT_PARAMS *
  396. DOLBY_PARAM_PAYLOAD_SIZE) *
  397. sizeof(uint32_t);
  398. pr_debug("%s\n", __func__);
  399. params_value = kzalloc(params_length, GFP_KERNEL);
  400. if (!params_value) {
  401. pr_err("%s, params memory alloc failed", __func__);
  402. return -ENOMEM;
  403. }
  404. update_params_value = (int *)params_value;
  405. for (idx = 0; idx < NUM_DOLBY_ENDP_DEVICE; idx++) {
  406. if (dolby_dap_endp_params[idx].device ==
  407. dolby_dap_params_states.device) {
  408. if (dolby_dap_params_states.device == AUX_DIGITAL ||
  409. dolby_dap_params_states.device == PROXY) {
  410. if (dolby_dap_endp_params[idx].device_ch_caps ==
  411. device_channels)
  412. break;
  413. } else {
  414. break;
  415. }
  416. }
  417. }
  418. if (idx >= NUM_DOLBY_ENDP_DEVICE) {
  419. pr_err("%s: device is not set accordingly\n", __func__);
  420. kfree(params_value);
  421. return -EINVAL;
  422. }
  423. for (i = 0; i < DOLBY_ENDDEP_PARAM_LENGTH; i++) {
  424. *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
  425. *update_params_value++ =
  426. dolby_dap_endp_params[idx].params_id[i];
  427. *update_params_value++ =
  428. dolby_dap_endp_params[idx].params_len[i] *
  429. sizeof(uint32_t);
  430. offset = dolby_dap_endp_params[idx].params_offset[i];
  431. for (j = 0; j < dolby_dap_endp_params[idx].params_len[i]; j++)
  432. *update_params_value++ =
  433. dolby_dap_endp_params[idx].params_val[offset+j];
  434. }
  435. rc = adm_dolby_dap_send_params(port_id, params_value, params_length);
  436. if (rc) {
  437. pr_err("%s: send dolby params failed\n", __func__);
  438. rc = -EINVAL;
  439. }
  440. kfree(params_value);
  441. return rc;
  442. }
  443. static int dolby_dap_send_cached_params(int port_id, int commit)
  444. {
  445. char *params_value;
  446. int *update_params_value, rc = 0;
  447. uint32_t index_offset, i, j;
  448. uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM +
  449. MAX_DOLBY_PARAMS * DOLBY_PARAM_PAYLOAD_SIZE) *
  450. sizeof(uint32_t);
  451. params_value = kzalloc(params_length, GFP_KERNEL);
  452. if (!params_value) {
  453. pr_err("%s, params memory alloc failed\n", __func__);
  454. return -ENOMEM;
  455. }
  456. update_params_value = (int *)params_value;
  457. params_length = 0;
  458. for (i = 0; i < MAX_DOLBY_PARAMS; i++) {
  459. if ((dolby_dap_params_modified[i] == 0) ||
  460. ((commit) &&
  461. ((dolby_dap_params_modified[i] & 0x00010000) &&
  462. ((dolby_dap_params_modified[i] & 0x0000FFFF) <= 1))))
  463. continue;
  464. *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
  465. *update_params_value++ = dolby_dap_params_id[i];
  466. *update_params_value++ = dolby_dap_params_length[i] *
  467. sizeof(uint32_t);
  468. index_offset = dolby_dap_params_offset[i];
  469. for (j = 0; j < dolby_dap_params_length[i]; j++)
  470. *update_params_value++ =
  471. dolby_dap_params_value[index_offset+j];
  472. params_length += (DOLBY_PARAM_PAYLOAD_SIZE +
  473. dolby_dap_params_length[i]) * sizeof(uint32_t);
  474. }
  475. pr_debug("%s, valid param length: %d", __func__, params_length);
  476. if (params_length) {
  477. rc = adm_dolby_dap_send_params(port_id, params_value,
  478. params_length);
  479. if (rc) {
  480. pr_err("%s: send dolby params failed\n", __func__);
  481. kfree(params_value);
  482. return -EINVAL;
  483. }
  484. for (i = 0; i < MAX_DOLBY_PARAMS; i++) {
  485. if ((dolby_dap_params_modified[i] == 0) ||
  486. ((commit) &&
  487. ((dolby_dap_params_modified[i] & 0x00010000) &&
  488. ((dolby_dap_params_modified[i] & 0x0000FFFF) <= 1))
  489. ))
  490. continue;
  491. dolby_dap_params_modified[i] = 0x00010001;
  492. }
  493. }
  494. kfree(params_value);
  495. return 0;
  496. }
  497. int dolby_dap_init(int port_id, int channels)
  498. {
  499. int ret = 0;
  500. if ((port_id != DOLBY_INVALID_PORT_ID) &&
  501. (port_id &
  502. dolby_dap_params_states.port_ids_dolby_can_be_enabled)) {
  503. dolby_dap_params_states.port_id = port_id;
  504. dolby_dap_params_states.port_open_count++;
  505. if (dolby_dap_params_states.auto_endp) {
  506. ret = dolby_dap_send_end_point(port_id);
  507. if (ret) {
  508. pr_err("%s: err sending endppoint\n", __func__);
  509. return ret;
  510. }
  511. }
  512. if (dolby_dap_params_states.use_cache) {
  513. ret = dolby_dap_send_cached_params(port_id, 0);
  514. if (ret) {
  515. pr_err("%s: err sending cached params\n",
  516. __func__);
  517. return ret;
  518. }
  519. }
  520. if (dolby_dap_params_states.enddep_params) {
  521. dolby_dap_send_enddep_params(port_id,
  522. channels);
  523. if (ret) {
  524. pr_err("%s: err sending endp dependent params\n",
  525. __func__);
  526. return ret;
  527. }
  528. }
  529. }
  530. return ret;
  531. }
  532. void dolby_dap_deinit(int port_id)
  533. {
  534. dolby_dap_params_states.port_open_count--;
  535. if ((dolby_dap_params_states.port_id == port_id) &&
  536. (!dolby_dap_params_states.port_open_count))
  537. dolby_dap_params_states.port_id = DOLBY_INVALID_PORT_ID;
  538. }
  539. static int map_device_to_port_id(int device)
  540. {
  541. int port_id = SLIMBUS_0_RX;
  542. device = DEVICE_OUT_ALL;
  543. /*update the device when single stream to multiple device is handled*/
  544. if (device == DEVICE_OUT_ALL) {
  545. port_id = PRIMARY_I2S_RX | SLIMBUS_0_RX | HDMI_RX |
  546. INT_BT_SCO_RX | INT_FM_RX |
  547. RT_PROXY_PORT_001_RX |
  548. AFE_PORT_ID_PRIMARY_PCM_RX |
  549. MI2S_RX | SECONDARY_I2S_RX |
  550. SLIMBUS_1_RX | SLIMBUS_4_RX | SLIMBUS_3_RX |
  551. AFE_PORT_ID_SECONDARY_MI2S_RX;
  552. } else {
  553. /* update port_id based on the device */
  554. }
  555. return port_id;
  556. }
  557. int msm_routing_get_dolby_dap_param_to_set_control(
  558. struct snd_kcontrol *kcontrol,
  559. struct snd_ctl_elem_value *ucontrol) {
  560. /* not used while setting the parameters */
  561. return 0;
  562. }
  563. int msm_routing_put_dolby_dap_param_to_set_control(
  564. struct snd_kcontrol *kcontrol,
  565. struct snd_ctl_elem_value *ucontrol) {
  566. int rc = 0;
  567. uint32_t idx, j, current_offset;
  568. uint32_t device = ucontrol->value.integer.value[0];
  569. uint32_t param_id = ucontrol->value.integer.value[1];
  570. uint32_t offset = ucontrol->value.integer.value[2];
  571. uint32_t length = ucontrol->value.integer.value[3];
  572. int port_id = dolby_dap_params_states.port_id;
  573. dolby_dap_params_states.port_ids_dolby_can_be_enabled =
  574. map_device_to_port_id(device);
  575. for (idx = 0; idx < ALL_DOLBY_PARAMS; idx++) {
  576. /*paramid from user space*/
  577. if (param_id == dolby_dap_params_id[idx])
  578. break;
  579. }
  580. if (idx > ALL_DOLBY_PARAMS-1) {
  581. pr_err("%s: invalid param id 0x%x to set\n", __func__,
  582. param_id);
  583. return -EINVAL;
  584. }
  585. switch (idx) {
  586. case DOLBY_COMMIT_ALL_IDX: {
  587. /* COMIIT ALL: Send all parameters to DSP */
  588. pr_debug("%s: COMMIT_ALL recvd\n", __func__);
  589. if (port_id != DOLBY_INVALID_PORT_ID)
  590. rc = dolby_dap_send_cached_params(port_id, 0);
  591. }
  592. break;
  593. case DOLBY_COMMIT_IDX: {
  594. pr_debug("%s: COMMIT recvd\n", __func__);
  595. /* COMMIT: Send only modified paramters to DSP */
  596. if (port_id != DOLBY_INVALID_PORT_ID)
  597. rc = dolby_dap_send_cached_params(port_id, 1);
  598. }
  599. break;
  600. case DOLBY_USE_CACHE_IDX: {
  601. pr_debug("%s: USE CACHE recvd val: %ld\n", __func__,
  602. ucontrol->value.integer.value[4]);
  603. dolby_dap_params_states.use_cache =
  604. ucontrol->value.integer.value[4];
  605. }
  606. break;
  607. case DOLBY_AUTO_ENDP_IDX: {
  608. pr_debug("%s: AUTO_ENDP recvd val: %ld\n", __func__,
  609. ucontrol->value.integer.value[4]);
  610. dolby_dap_params_states.auto_endp =
  611. ucontrol->value.integer.value[4];
  612. }
  613. break;
  614. case DOLBY_AUTO_ENDDEP_IDX: {
  615. pr_debug("%s: USE_ENDDEP_PARAMS recvd val: %ld\n",
  616. __func__, ucontrol->value.integer.value[4]);
  617. dolby_dap_params_states.enddep_params =
  618. ucontrol->value.integer.value[4];
  619. }
  620. break;
  621. default: {
  622. /* cache the parameters */
  623. dolby_dap_params_modified[idx] += 1;
  624. current_offset = dolby_dap_params_offset[idx] + offset;
  625. if (current_offset >= TOTAL_LENGTH_DOLBY_PARAM) {
  626. pr_err("%s: invalid offset %d at idx %d\n",
  627. __func__, offset, idx);
  628. return -EINVAL;
  629. }
  630. if ((0 == length) || (current_offset + length - 1
  631. < current_offset) || (current_offset + length
  632. > TOTAL_LENGTH_DOLBY_PARAM)) {
  633. pr_err("%s: invalid length %d at idx %d\n",
  634. __func__, length, idx);
  635. return -EINVAL;
  636. }
  637. dolby_dap_params_length[idx] = length;
  638. pr_debug("%s: param recvd deviceId=0x%x paramId=0x%x offset=%d length=%d\n",
  639. __func__, device, param_id, offset, length);
  640. for (j = 0; j < length; j++) {
  641. dolby_dap_params_value[
  642. dolby_dap_params_offset[idx] +
  643. offset + j]
  644. = ucontrol->value.integer.value[4+j];
  645. pr_debug("value[%d]: %ld\n", j,
  646. ucontrol->value.integer.value[4+j]);
  647. }
  648. }
  649. }
  650. return rc;
  651. }
  652. int msm_routing_get_dolby_dap_param_to_get_control(
  653. struct snd_kcontrol *kcontrol,
  654. struct snd_ctl_elem_value *ucontrol) {
  655. int rc = 0, i;
  656. char *params_value;
  657. int *update_params_value;
  658. uint32_t params_length = DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM *
  659. sizeof(uint32_t);
  660. uint32_t param_payload_len =
  661. DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t);
  662. int port_id = dolby_dap_params_states.port_id;
  663. if (port_id == DOLBY_INVALID_PORT_ID) {
  664. pr_err("%s, port_id not set, returning error", __func__);
  665. return -EINVAL;
  666. }
  667. params_value = kzalloc(params_length, GFP_KERNEL);
  668. if (!params_value) {
  669. pr_err("%s, params memory alloc failed\n", __func__);
  670. return -ENOMEM;
  671. }
  672. if (DOLBY_PARAM_ID_VER == dolby_dap_params_get.param_id) {
  673. rc = adm_get_params(dolby_dap_params_get.port_id,
  674. DOLBY_BUNDLE_MODULE_ID,
  675. DOLBY_PARAM_ID_VER,
  676. params_length +
  677. param_payload_len,
  678. params_value);
  679. } else {
  680. for (i = 0; i < MAX_DOLBY_PARAMS; i++)
  681. if (dolby_dap_params_id[i] ==
  682. dolby_dap_params_get.param_id)
  683. break;
  684. if (i > MAX_DOLBY_PARAMS-1) {
  685. pr_err("%s: invalid param id to set", __func__);
  686. rc = -EINVAL;
  687. } else {
  688. params_length = (dolby_dap_params_length[i] +
  689. DOLBY_PARAM_PAYLOAD_SIZE) *
  690. sizeof(uint32_t);
  691. rc = adm_get_params(
  692. dolby_dap_params_get.port_id,
  693. DOLBY_BUNDLE_MODULE_ID,
  694. dolby_dap_params_id[i],
  695. params_length +
  696. param_payload_len,
  697. params_value);
  698. }
  699. }
  700. if (rc) {
  701. pr_err("%s: get parameters failed\n", __func__);
  702. kfree(params_value);
  703. return -EINVAL;
  704. }
  705. update_params_value = (int *)params_value;
  706. ucontrol->value.integer.value[0] = dolby_dap_params_get.device_id;
  707. ucontrol->value.integer.value[1] = dolby_dap_params_get.param_id;
  708. ucontrol->value.integer.value[2] = dolby_dap_params_get.offset;
  709. ucontrol->value.integer.value[3] = dolby_dap_params_get.length;
  710. pr_debug("%s: FROM DSP value[0] 0x%x value[1] %d value[2] 0x%x\n",
  711. __func__, update_params_value[0],
  712. update_params_value[1], update_params_value[2]);
  713. for (i = 0; i < dolby_dap_params_get.length; i++) {
  714. ucontrol->value.integer.value[DOLBY_PARAM_PAYLOAD_SIZE+i] =
  715. update_params_value[i];
  716. pr_debug("value[%d]:%d\n", i, update_params_value[i]);
  717. }
  718. pr_debug("%s: Returning param_id=0x%x offset=%d length=%d\n",
  719. __func__, dolby_dap_params_get.param_id,
  720. dolby_dap_params_get.offset,
  721. dolby_dap_params_get.length);
  722. kfree(params_value);
  723. return 0;
  724. }
  725. int msm_routing_put_dolby_dap_param_to_get_control(
  726. struct snd_kcontrol *kcontrol,
  727. struct snd_ctl_elem_value *ucontrol) {
  728. dolby_dap_params_get.device_id = ucontrol->value.integer.value[0];
  729. dolby_dap_params_get.port_id =
  730. (dolby_dap_params_get.device_id == DEVICE_OUT_ALL) ?
  731. dolby_dap_params_states.port_id :
  732. map_device_to_port_id(dolby_dap_params_get.device_id);
  733. dolby_dap_params_get.param_id = ucontrol->value.integer.value[1];
  734. dolby_dap_params_get.offset = ucontrol->value.integer.value[2];
  735. dolby_dap_params_get.length = ucontrol->value.integer.value[3];
  736. pr_debug("%s: param_id=0x%x offset=%d length=%d\n", __func__,
  737. dolby_dap_params_get.param_id, dolby_dap_params_get.offset,
  738. dolby_dap_params_get.length);
  739. return 0;
  740. }
  741. int msm_routing_get_dolby_dap_param_visualizer_control(
  742. struct snd_kcontrol *kcontrol,
  743. struct snd_ctl_elem_value *ucontrol) {
  744. uint32_t length = dolby_dap_params_value[DOLBY_PARAM_VCNB_OFFSET];
  745. char *visualizer_data;
  746. int i, rc;
  747. int *update_visualizer_data;
  748. uint32_t offset, params_length =
  749. (2*length + DOLBY_VIS_PARAM_HEADER_SIZE)*sizeof(uint32_t);
  750. uint32_t param_payload_len =
  751. DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t);
  752. int port_id = dolby_dap_params_states.port_id;
  753. if (port_id == DOLBY_INVALID_PORT_ID) {
  754. pr_debug("%s, port_id not set, returning error", __func__);
  755. ucontrol->value.integer.value[0] = 0;
  756. return -EINVAL;
  757. }
  758. if (length > DOLBY_PARAM_VCNB_MAX_LENGTH || length <= 0) {
  759. pr_err("%s Incorrect VCNB length", __func__);
  760. ucontrol->value.integer.value[0] = 0;
  761. return -EINVAL;
  762. }
  763. visualizer_data = kzalloc(params_length, GFP_KERNEL);
  764. if (!visualizer_data) {
  765. pr_err("%s, params memory alloc failed\n", __func__);
  766. return -ENOMEM;
  767. }
  768. offset = 0;
  769. params_length = length * sizeof(uint32_t);
  770. rc = adm_get_params(dolby_dap_params_states.port_id,
  771. DOLBY_BUNDLE_MODULE_ID,
  772. DOLBY_PARAM_ID_VCBG,
  773. params_length + param_payload_len,
  774. visualizer_data + offset);
  775. if (rc) {
  776. pr_err("%s: get parameters failed\n", __func__);
  777. kfree(visualizer_data);
  778. return -EINVAL;
  779. }
  780. offset = length * sizeof(uint32_t);
  781. rc = adm_get_params(dolby_dap_params_states.port_id,
  782. DOLBY_BUNDLE_MODULE_ID,
  783. DOLBY_PARAM_ID_VCBE,
  784. params_length + param_payload_len,
  785. visualizer_data + offset);
  786. if (rc) {
  787. pr_err("%s: get parameters failed\n", __func__);
  788. kfree(visualizer_data);
  789. return -EINVAL;
  790. }
  791. ucontrol->value.integer.value[0] = 2*length;
  792. pr_debug("%s: visualizer data length %ld\n", __func__,
  793. ucontrol->value.integer.value[0]);
  794. update_visualizer_data = (int *)visualizer_data;
  795. for (i = 0; i < 2*length; i++) {
  796. ucontrol->value.integer.value[1+i] = update_visualizer_data[i];
  797. pr_debug("value[%d] %d\n", i, update_visualizer_data[i]);
  798. }
  799. kfree(visualizer_data);
  800. return 0;
  801. }
  802. int msm_routing_put_dolby_dap_param_visualizer_control(
  803. struct snd_kcontrol *kcontrol,
  804. struct snd_ctl_elem_value *ucontrol) {
  805. /* not used while getting the visualizer data */
  806. return 0;
  807. }
  808. int msm_routing_get_dolby_dap_endpoint_control(
  809. struct snd_kcontrol *kcontrol,
  810. struct snd_ctl_elem_value *ucontrol) {
  811. /* not used while setting the endpoint */
  812. return 0;
  813. }
  814. int msm_routing_put_dolby_dap_endpoint_control(
  815. struct snd_kcontrol *kcontrol,
  816. struct snd_ctl_elem_value *ucontrol) {
  817. int device = ucontrol->value.integer.value[0];
  818. dolby_dap_params_states.device = device;
  819. return 0;
  820. }