q6routing.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
  3. // Copyright (c) 2018, Linaro Limited
  4. #include <linux/init.h>
  5. #include <linux/err.h>
  6. #include <linux/module.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/of_platform.h>
  9. #include <linux/bitops.h>
  10. #include <linux/mutex.h>
  11. #include <linux/of_device.h>
  12. #include <linux/slab.h>
  13. #include <sound/core.h>
  14. #include <sound/soc.h>
  15. #include <sound/soc-dapm.h>
  16. #include <sound/pcm.h>
  17. #include <sound/control.h>
  18. #include <sound/asound.h>
  19. #include <sound/pcm_params.h>
  20. #include "q6afe.h"
  21. #include "q6asm.h"
  22. #include "q6adm.h"
  23. #include "q6routing.h"
  24. #define DRV_NAME "q6routing-component"
  25. #define Q6ROUTING_RX_MIXERS(id) \
  26. SOC_SINGLE_EXT("MultiMedia1", id, \
  27. MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,\
  28. msm_routing_put_audio_mixer), \
  29. SOC_SINGLE_EXT("MultiMedia2", id, \
  30. MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,\
  31. msm_routing_put_audio_mixer), \
  32. SOC_SINGLE_EXT("MultiMedia3", id, \
  33. MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,\
  34. msm_routing_put_audio_mixer), \
  35. SOC_SINGLE_EXT("MultiMedia4", id, \
  36. MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,\
  37. msm_routing_put_audio_mixer), \
  38. SOC_SINGLE_EXT("MultiMedia5", id, \
  39. MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,\
  40. msm_routing_put_audio_mixer), \
  41. SOC_SINGLE_EXT("MultiMedia6", id, \
  42. MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,\
  43. msm_routing_put_audio_mixer), \
  44. SOC_SINGLE_EXT("MultiMedia7", id, \
  45. MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,\
  46. msm_routing_put_audio_mixer), \
  47. SOC_SINGLE_EXT("MultiMedia8", id, \
  48. MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,\
  49. msm_routing_put_audio_mixer),
  50. #define Q6ROUTING_RX_DAPM_ROUTE(mix_name, s) \
  51. { mix_name, "MultiMedia1", "MM_DL1" }, \
  52. { mix_name, "MultiMedia2", "MM_DL2" }, \
  53. { mix_name, "MultiMedia3", "MM_DL3" }, \
  54. { mix_name, "MultiMedia4", "MM_DL4" }, \
  55. { mix_name, "MultiMedia5", "MM_DL5" }, \
  56. { mix_name, "MultiMedia6", "MM_DL6" }, \
  57. { mix_name, "MultiMedia7", "MM_DL7" }, \
  58. { mix_name, "MultiMedia8", "MM_DL8" }, \
  59. { s, NULL, mix_name }
  60. #define Q6ROUTING_TX_DAPM_ROUTE(mix_name) \
  61. { mix_name, "PRI_MI2S_TX", "PRI_MI2S_TX" }, \
  62. { mix_name, "SEC_MI2S_TX", "SEC_MI2S_TX" }, \
  63. { mix_name, "QUAT_MI2S_TX", "QUAT_MI2S_TX" }, \
  64. { mix_name, "TERT_MI2S_TX", "TERT_MI2S_TX" }, \
  65. { mix_name, "SLIMBUS_0_TX", "SLIMBUS_0_TX" }, \
  66. { mix_name, "SLIMBUS_1_TX", "SLIMBUS_1_TX" }, \
  67. { mix_name, "SLIMBUS_2_TX", "SLIMBUS_2_TX" }, \
  68. { mix_name, "SLIMBUS_3_TX", "SLIMBUS_3_TX" }, \
  69. { mix_name, "SLIMBUS_4_TX", "SLIMBUS_4_TX" }, \
  70. { mix_name, "SLIMBUS_5_TX", "SLIMBUS_5_TX" }, \
  71. { mix_name, "SLIMBUS_6_TX", "SLIMBUS_6_TX" }, \
  72. { mix_name, "PRIMARY_TDM_TX_0", "PRIMARY_TDM_TX_0"}, \
  73. { mix_name, "PRIMARY_TDM_TX_1", "PRIMARY_TDM_TX_1"}, \
  74. { mix_name, "PRIMARY_TDM_TX_2", "PRIMARY_TDM_TX_2"}, \
  75. { mix_name, "PRIMARY_TDM_TX_3", "PRIMARY_TDM_TX_3"}, \
  76. { mix_name, "PRIMARY_TDM_TX_4", "PRIMARY_TDM_TX_4"}, \
  77. { mix_name, "PRIMARY_TDM_TX_5", "PRIMARY_TDM_TX_5"}, \
  78. { mix_name, "PRIMARY_TDM_TX_6", "PRIMARY_TDM_TX_6"}, \
  79. { mix_name, "PRIMARY_TDM_TX_7", "PRIMARY_TDM_TX_7"}, \
  80. { mix_name, "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, \
  81. { mix_name, "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, \
  82. { mix_name, "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, \
  83. { mix_name, "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, \
  84. { mix_name, "SEC_TDM_TX_4", "SEC_TDM_TX_4"}, \
  85. { mix_name, "SEC_TDM_TX_5", "SEC_TDM_TX_5"}, \
  86. { mix_name, "SEC_TDM_TX_6", "SEC_TDM_TX_6"}, \
  87. { mix_name, "SEC_TDM_TX_7", "SEC_TDM_TX_7"}, \
  88. { mix_name, "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, \
  89. { mix_name, "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, \
  90. { mix_name, "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, \
  91. { mix_name, "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, \
  92. { mix_name, "TERT_TDM_TX_4", "TERT_TDM_TX_4"}, \
  93. { mix_name, "TERT_TDM_TX_5", "TERT_TDM_TX_5"}, \
  94. { mix_name, "TERT_TDM_TX_6", "TERT_TDM_TX_6"}, \
  95. { mix_name, "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, \
  96. { mix_name, "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, \
  97. { mix_name, "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, \
  98. { mix_name, "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, \
  99. { mix_name, "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, \
  100. { mix_name, "QUAT_TDM_TX_4", "QUAT_TDM_TX_4"}, \
  101. { mix_name, "QUAT_TDM_TX_5", "QUAT_TDM_TX_5"}, \
  102. { mix_name, "QUAT_TDM_TX_6", "QUAT_TDM_TX_6"}, \
  103. { mix_name, "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, \
  104. { mix_name, "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, \
  105. { mix_name, "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, \
  106. { mix_name, "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, \
  107. { mix_name, "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, \
  108. { mix_name, "QUIN_TDM_TX_4", "QUIN_TDM_TX_4"}, \
  109. { mix_name, "QUIN_TDM_TX_5", "QUIN_TDM_TX_5"}, \
  110. { mix_name, "QUIN_TDM_TX_6", "QUIN_TDM_TX_6"}, \
  111. { mix_name, "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}
  112. #define Q6ROUTING_TX_MIXERS(id) \
  113. SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, \
  114. id, 1, 0, msm_routing_get_audio_mixer, \
  115. msm_routing_put_audio_mixer), \
  116. SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, \
  117. id, 1, 0, msm_routing_get_audio_mixer, \
  118. msm_routing_put_audio_mixer), \
  119. SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, \
  120. id, 1, 0, msm_routing_get_audio_mixer, \
  121. msm_routing_put_audio_mixer), \
  122. SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, \
  123. id, 1, 0, msm_routing_get_audio_mixer, \
  124. msm_routing_put_audio_mixer), \
  125. SOC_SINGLE_EXT("SLIMBUS_0_TX", SLIMBUS_0_TX, \
  126. id, 1, 0, msm_routing_get_audio_mixer, \
  127. msm_routing_put_audio_mixer), \
  128. SOC_SINGLE_EXT("SLIMBUS_1_TX", SLIMBUS_1_TX, \
  129. id, 1, 0, msm_routing_get_audio_mixer, \
  130. msm_routing_put_audio_mixer), \
  131. SOC_SINGLE_EXT("SLIMBUS_2_TX", SLIMBUS_2_TX, \
  132. id, 1, 0, msm_routing_get_audio_mixer, \
  133. msm_routing_put_audio_mixer), \
  134. SOC_SINGLE_EXT("SLIMBUS_3_TX", SLIMBUS_3_TX, \
  135. id, 1, 0, msm_routing_get_audio_mixer, \
  136. msm_routing_put_audio_mixer), \
  137. SOC_SINGLE_EXT("SLIMBUS_4_TX", SLIMBUS_4_TX, \
  138. id, 1, 0, msm_routing_get_audio_mixer, \
  139. msm_routing_put_audio_mixer), \
  140. SOC_SINGLE_EXT("SLIMBUS_5_TX", SLIMBUS_5_TX, \
  141. id, 1, 0, msm_routing_get_audio_mixer, \
  142. msm_routing_put_audio_mixer), \
  143. SOC_SINGLE_EXT("SLIMBUS_6_TX", SLIMBUS_6_TX, \
  144. id, 1, 0, msm_routing_get_audio_mixer, \
  145. msm_routing_put_audio_mixer), \
  146. SOC_SINGLE_EXT("PRIMARY_TDM_TX_0", PRIMARY_TDM_TX_0, \
  147. id, 1, 0, msm_routing_get_audio_mixer, \
  148. msm_routing_put_audio_mixer), \
  149. SOC_SINGLE_EXT("PRIMARY_TDM_TX_1", PRIMARY_TDM_TX_1, \
  150. id, 1, 0, msm_routing_get_audio_mixer, \
  151. msm_routing_put_audio_mixer), \
  152. SOC_SINGLE_EXT("PRIMARY_TDM_TX_2", PRIMARY_TDM_TX_2, \
  153. id, 1, 0, msm_routing_get_audio_mixer, \
  154. msm_routing_put_audio_mixer), \
  155. SOC_SINGLE_EXT("PRIMARY_TDM_TX_3", PRIMARY_TDM_TX_3, \
  156. id, 1, 0, msm_routing_get_audio_mixer, \
  157. msm_routing_put_audio_mixer), \
  158. SOC_SINGLE_EXT("PRIMARY_TDM_TX_4", PRIMARY_TDM_TX_4, \
  159. id, 1, 0, msm_routing_get_audio_mixer, \
  160. msm_routing_put_audio_mixer), \
  161. SOC_SINGLE_EXT("PRIMARY_TDM_TX_5", PRIMARY_TDM_TX_5, \
  162. id, 1, 0, msm_routing_get_audio_mixer, \
  163. msm_routing_put_audio_mixer), \
  164. SOC_SINGLE_EXT("PRIMARY_TDM_TX_6", PRIMARY_TDM_TX_6, \
  165. id, 1, 0, msm_routing_get_audio_mixer, \
  166. msm_routing_put_audio_mixer), \
  167. SOC_SINGLE_EXT("PRIMARY_TDM_TX_7", PRIMARY_TDM_TX_7, \
  168. id, 1, 0, msm_routing_get_audio_mixer, \
  169. msm_routing_put_audio_mixer), \
  170. SOC_SINGLE_EXT("SEC_TDM_TX_0", SECONDARY_TDM_TX_0, \
  171. id, 1, 0, msm_routing_get_audio_mixer, \
  172. msm_routing_put_audio_mixer), \
  173. SOC_SINGLE_EXT("SEC_TDM_TX_1", SECONDARY_TDM_TX_1, \
  174. id, 1, 0, msm_routing_get_audio_mixer, \
  175. msm_routing_put_audio_mixer), \
  176. SOC_SINGLE_EXT("SEC_TDM_TX_2", SECONDARY_TDM_TX_2, \
  177. id, 1, 0, msm_routing_get_audio_mixer, \
  178. msm_routing_put_audio_mixer), \
  179. SOC_SINGLE_EXT("SEC_TDM_TX_3", SECONDARY_TDM_TX_3, \
  180. id, 1, 0, msm_routing_get_audio_mixer, \
  181. msm_routing_put_audio_mixer), \
  182. SOC_SINGLE_EXT("SEC_TDM_TX_4", SECONDARY_TDM_TX_4, \
  183. id, 1, 0, msm_routing_get_audio_mixer, \
  184. msm_routing_put_audio_mixer), \
  185. SOC_SINGLE_EXT("SEC_TDM_TX_5", SECONDARY_TDM_TX_5, \
  186. id, 1, 0, msm_routing_get_audio_mixer, \
  187. msm_routing_put_audio_mixer), \
  188. SOC_SINGLE_EXT("SEC_TDM_TX_6", SECONDARY_TDM_TX_6, \
  189. id, 1, 0, msm_routing_get_audio_mixer, \
  190. msm_routing_put_audio_mixer), \
  191. SOC_SINGLE_EXT("SEC_TDM_TX_7", SECONDARY_TDM_TX_7, \
  192. id, 1, 0, msm_routing_get_audio_mixer, \
  193. msm_routing_put_audio_mixer), \
  194. SOC_SINGLE_EXT("TERT_TDM_TX_0", TERTIARY_TDM_TX_0, \
  195. id, 1, 0, msm_routing_get_audio_mixer, \
  196. msm_routing_put_audio_mixer), \
  197. SOC_SINGLE_EXT("TERT_TDM_TX_1", TERTIARY_TDM_TX_1, \
  198. id, 1, 0, msm_routing_get_audio_mixer, \
  199. msm_routing_put_audio_mixer), \
  200. SOC_SINGLE_EXT("TERT_TDM_TX_2", TERTIARY_TDM_TX_2, \
  201. id, 1, 0, msm_routing_get_audio_mixer, \
  202. msm_routing_put_audio_mixer), \
  203. SOC_SINGLE_EXT("TERT_TDM_TX_3", TERTIARY_TDM_TX_3, \
  204. id, 1, 0, msm_routing_get_audio_mixer, \
  205. msm_routing_put_audio_mixer), \
  206. SOC_SINGLE_EXT("TERT_TDM_TX_4", TERTIARY_TDM_TX_4, \
  207. id, 1, 0, msm_routing_get_audio_mixer, \
  208. msm_routing_put_audio_mixer), \
  209. SOC_SINGLE_EXT("TERT_TDM_TX_5", TERTIARY_TDM_TX_5, \
  210. id, 1, 0, msm_routing_get_audio_mixer, \
  211. msm_routing_put_audio_mixer), \
  212. SOC_SINGLE_EXT("TERT_TDM_TX_6", TERTIARY_TDM_TX_6, \
  213. id, 1, 0, msm_routing_get_audio_mixer, \
  214. msm_routing_put_audio_mixer), \
  215. SOC_SINGLE_EXT("TERT_TDM_TX_7", TERTIARY_TDM_TX_7, \
  216. id, 1, 0, msm_routing_get_audio_mixer, \
  217. msm_routing_put_audio_mixer), \
  218. SOC_SINGLE_EXT("QUAT_TDM_TX_0", QUATERNARY_TDM_TX_0, \
  219. id, 1, 0, msm_routing_get_audio_mixer, \
  220. msm_routing_put_audio_mixer), \
  221. SOC_SINGLE_EXT("QUAT_TDM_TX_1", QUATERNARY_TDM_TX_1, \
  222. id, 1, 0, msm_routing_get_audio_mixer, \
  223. msm_routing_put_audio_mixer), \
  224. SOC_SINGLE_EXT("QUAT_TDM_TX_2", QUATERNARY_TDM_TX_2, \
  225. id, 1, 0, msm_routing_get_audio_mixer, \
  226. msm_routing_put_audio_mixer), \
  227. SOC_SINGLE_EXT("QUAT_TDM_TX_3", QUATERNARY_TDM_TX_3, \
  228. id, 1, 0, msm_routing_get_audio_mixer, \
  229. msm_routing_put_audio_mixer), \
  230. SOC_SINGLE_EXT("QUAT_TDM_TX_4", QUATERNARY_TDM_TX_4, \
  231. id, 1, 0, msm_routing_get_audio_mixer, \
  232. msm_routing_put_audio_mixer), \
  233. SOC_SINGLE_EXT("QUAT_TDM_TX_5", QUATERNARY_TDM_TX_5, \
  234. id, 1, 0, msm_routing_get_audio_mixer, \
  235. msm_routing_put_audio_mixer), \
  236. SOC_SINGLE_EXT("QUAT_TDM_TX_6", QUATERNARY_TDM_TX_6, \
  237. id, 1, 0, msm_routing_get_audio_mixer, \
  238. msm_routing_put_audio_mixer), \
  239. SOC_SINGLE_EXT("QUAT_TDM_TX_7", QUATERNARY_TDM_TX_7, \
  240. id, 1, 0, msm_routing_get_audio_mixer, \
  241. msm_routing_put_audio_mixer), \
  242. SOC_SINGLE_EXT("QUIN_TDM_TX_0", QUINARY_TDM_TX_0, \
  243. id, 1, 0, msm_routing_get_audio_mixer, \
  244. msm_routing_put_audio_mixer), \
  245. SOC_SINGLE_EXT("QUIN_TDM_TX_1", QUINARY_TDM_TX_1, \
  246. id, 1, 0, msm_routing_get_audio_mixer, \
  247. msm_routing_put_audio_mixer), \
  248. SOC_SINGLE_EXT("QUIN_TDM_TX_2", QUINARY_TDM_TX_2, \
  249. id, 1, 0, msm_routing_get_audio_mixer, \
  250. msm_routing_put_audio_mixer), \
  251. SOC_SINGLE_EXT("QUIN_TDM_TX_3", QUINARY_TDM_TX_3, \
  252. id, 1, 0, msm_routing_get_audio_mixer, \
  253. msm_routing_put_audio_mixer), \
  254. SOC_SINGLE_EXT("QUIN_TDM_TX_4", QUINARY_TDM_TX_4, \
  255. id, 1, 0, msm_routing_get_audio_mixer, \
  256. msm_routing_put_audio_mixer), \
  257. SOC_SINGLE_EXT("QUIN_TDM_TX_5", QUINARY_TDM_TX_5, \
  258. id, 1, 0, msm_routing_get_audio_mixer, \
  259. msm_routing_put_audio_mixer), \
  260. SOC_SINGLE_EXT("QUIN_TDM_TX_6", QUINARY_TDM_TX_6, \
  261. id, 1, 0, msm_routing_get_audio_mixer, \
  262. msm_routing_put_audio_mixer), \
  263. SOC_SINGLE_EXT("QUIN_TDM_TX_7", QUINARY_TDM_TX_7, \
  264. id, 1, 0, msm_routing_get_audio_mixer, \
  265. msm_routing_put_audio_mixer),
  266. struct session_data {
  267. int state;
  268. int port_id;
  269. int path_type;
  270. int app_type;
  271. int acdb_id;
  272. int sample_rate;
  273. int bits_per_sample;
  274. int channels;
  275. int perf_mode;
  276. int numcopps;
  277. int fedai_id;
  278. unsigned long copp_map;
  279. struct q6copp *copps[MAX_COPPS_PER_PORT];
  280. };
  281. struct msm_routing_data {
  282. struct session_data sessions[MAX_SESSIONS];
  283. struct session_data port_data[AFE_MAX_PORTS];
  284. struct device *dev;
  285. struct mutex lock;
  286. };
  287. static struct msm_routing_data *routing_data;
  288. /**
  289. * q6routing_stream_open() - Register a new stream for route setup
  290. *
  291. * @fedai_id: Frontend dai id.
  292. * @perf_mode: Performance mode.
  293. * @stream_id: ASM stream id to map.
  294. * @stream_type: Direction of stream
  295. *
  296. * Return: Will be an negative on error or a zero on success.
  297. */
  298. int q6routing_stream_open(int fedai_id, int perf_mode,
  299. int stream_id, int stream_type)
  300. {
  301. int j, topology, num_copps = 0;
  302. struct route_payload payload;
  303. struct q6copp *copp;
  304. int copp_idx;
  305. struct session_data *session, *pdata;
  306. if (!routing_data) {
  307. pr_err("Routing driver not yet ready\n");
  308. return -EINVAL;
  309. }
  310. session = &routing_data->sessions[stream_id - 1];
  311. pdata = &routing_data->port_data[session->port_id];
  312. mutex_lock(&routing_data->lock);
  313. session->fedai_id = fedai_id;
  314. session->path_type = pdata->path_type;
  315. session->sample_rate = pdata->sample_rate;
  316. session->channels = pdata->channels;
  317. session->bits_per_sample = pdata->bits_per_sample;
  318. payload.num_copps = 0; /* only RX needs to use payload */
  319. topology = NULL_COPP_TOPOLOGY;
  320. copp = q6adm_open(routing_data->dev, session->port_id,
  321. session->path_type, session->sample_rate,
  322. session->channels, topology, perf_mode,
  323. session->bits_per_sample, 0, 0);
  324. if (IS_ERR_OR_NULL(copp)) {
  325. mutex_unlock(&routing_data->lock);
  326. return -EINVAL;
  327. }
  328. copp_idx = q6adm_get_copp_id(copp);
  329. set_bit(copp_idx, &session->copp_map);
  330. session->copps[copp_idx] = copp;
  331. for_each_set_bit(j, &session->copp_map, MAX_COPPS_PER_PORT) {
  332. payload.port_id[num_copps] = session->port_id;
  333. payload.copp_idx[num_copps] = j;
  334. num_copps++;
  335. }
  336. if (num_copps) {
  337. payload.num_copps = num_copps;
  338. payload.session_id = stream_id;
  339. q6adm_matrix_map(routing_data->dev, session->path_type,
  340. payload, perf_mode);
  341. }
  342. mutex_unlock(&routing_data->lock);
  343. return 0;
  344. }
  345. EXPORT_SYMBOL_GPL(q6routing_stream_open);
  346. static struct session_data *get_session_from_id(struct msm_routing_data *data,
  347. int fedai_id)
  348. {
  349. int i;
  350. for (i = 0; i < MAX_SESSIONS; i++) {
  351. if (fedai_id == data->sessions[i].fedai_id)
  352. return &data->sessions[i];
  353. }
  354. return NULL;
  355. }
  356. /**
  357. * q6routing_stream_close() - Deregister a stream
  358. *
  359. * @fedai_id: Frontend dai id.
  360. * @stream_type: Direction of stream
  361. *
  362. * Return: Will be an negative on error or a zero on success.
  363. */
  364. void q6routing_stream_close(int fedai_id, int stream_type)
  365. {
  366. struct session_data *session;
  367. int idx;
  368. session = get_session_from_id(routing_data, fedai_id);
  369. if (!session)
  370. return;
  371. for_each_set_bit(idx, &session->copp_map, MAX_COPPS_PER_PORT) {
  372. if (session->copps[idx]) {
  373. q6adm_close(routing_data->dev, session->copps[idx]);
  374. session->copps[idx] = NULL;
  375. }
  376. }
  377. session->fedai_id = -1;
  378. session->copp_map = 0;
  379. }
  380. EXPORT_SYMBOL_GPL(q6routing_stream_close);
  381. static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
  382. struct snd_ctl_elem_value *ucontrol)
  383. {
  384. struct snd_soc_dapm_context *dapm =
  385. snd_soc_dapm_kcontrol_dapm(kcontrol);
  386. struct soc_mixer_control *mc =
  387. (struct soc_mixer_control *)kcontrol->private_value;
  388. int session_id = mc->shift;
  389. struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
  390. struct msm_routing_data *priv = dev_get_drvdata(c->dev);
  391. struct session_data *session = &priv->sessions[session_id];
  392. if (session->port_id == mc->reg)
  393. ucontrol->value.integer.value[0] = 1;
  394. else
  395. ucontrol->value.integer.value[0] = 0;
  396. return 0;
  397. }
  398. static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
  399. struct snd_ctl_elem_value *ucontrol)
  400. {
  401. struct snd_soc_dapm_context *dapm =
  402. snd_soc_dapm_kcontrol_dapm(kcontrol);
  403. struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
  404. struct msm_routing_data *data = dev_get_drvdata(c->dev);
  405. struct soc_mixer_control *mc =
  406. (struct soc_mixer_control *)kcontrol->private_value;
  407. struct snd_soc_dapm_update *update = NULL;
  408. int be_id = mc->reg;
  409. int session_id = mc->shift;
  410. struct session_data *session = &data->sessions[session_id];
  411. if (ucontrol->value.integer.value[0]) {
  412. session->port_id = be_id;
  413. snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, update);
  414. } else {
  415. session->port_id = -1;
  416. snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, update);
  417. }
  418. return 1;
  419. }
  420. static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
  421. Q6ROUTING_RX_MIXERS(HDMI_RX) };
  422. static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
  423. Q6ROUTING_RX_MIXERS(PRIMARY_MI2S_RX) };
  424. static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = {
  425. Q6ROUTING_RX_MIXERS(SECONDARY_MI2S_RX) };
  426. static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = {
  427. Q6ROUTING_RX_MIXERS(QUATERNARY_MI2S_RX) };
  428. static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = {
  429. Q6ROUTING_RX_MIXERS(TERTIARY_MI2S_RX) };
  430. static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
  431. Q6ROUTING_RX_MIXERS(SLIMBUS_0_RX) };
  432. static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = {
  433. Q6ROUTING_RX_MIXERS(SLIMBUS_1_RX) };
  434. static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = {
  435. Q6ROUTING_RX_MIXERS(SLIMBUS_2_RX) };
  436. static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = {
  437. Q6ROUTING_RX_MIXERS(SLIMBUS_3_RX) };
  438. static const struct snd_kcontrol_new slimbus_4_rx_mixer_controls[] = {
  439. Q6ROUTING_RX_MIXERS(SLIMBUS_4_RX) };
  440. static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = {
  441. Q6ROUTING_RX_MIXERS(SLIMBUS_5_RX) };
  442. static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = {
  443. Q6ROUTING_RX_MIXERS(SLIMBUS_6_RX) };
  444. static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = {
  445. Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_0) };
  446. static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = {
  447. Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_1) };
  448. static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = {
  449. Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_2) };
  450. static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = {
  451. Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_3) };
  452. static const struct snd_kcontrol_new pri_tdm_rx_4_mixer_controls[] = {
  453. Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_4) };
  454. static const struct snd_kcontrol_new pri_tdm_rx_5_mixer_controls[] = {
  455. Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_5) };
  456. static const struct snd_kcontrol_new pri_tdm_rx_6_mixer_controls[] = {
  457. Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_6) };
  458. static const struct snd_kcontrol_new pri_tdm_rx_7_mixer_controls[] = {
  459. Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_7) };
  460. static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = {
  461. Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_0) };
  462. static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = {
  463. Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_1) };
  464. static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = {
  465. Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_2) };
  466. static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = {
  467. Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_3) };
  468. static const struct snd_kcontrol_new sec_tdm_rx_4_mixer_controls[] = {
  469. Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_4) };
  470. static const struct snd_kcontrol_new sec_tdm_rx_5_mixer_controls[] = {
  471. Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_5) };
  472. static const struct snd_kcontrol_new sec_tdm_rx_6_mixer_controls[] = {
  473. Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_6) };
  474. static const struct snd_kcontrol_new sec_tdm_rx_7_mixer_controls[] = {
  475. Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_7) };
  476. static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = {
  477. Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_0) };
  478. static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = {
  479. Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_1) };
  480. static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = {
  481. Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_2) };
  482. static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = {
  483. Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_3) };
  484. static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = {
  485. Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_4) };
  486. static const struct snd_kcontrol_new tert_tdm_rx_5_mixer_controls[] = {
  487. Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_5) };
  488. static const struct snd_kcontrol_new tert_tdm_rx_6_mixer_controls[] = {
  489. Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_6) };
  490. static const struct snd_kcontrol_new tert_tdm_rx_7_mixer_controls[] = {
  491. Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_7) };
  492. static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = {
  493. Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_0) };
  494. static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = {
  495. Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_1) };
  496. static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = {
  497. Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_2) };
  498. static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = {
  499. Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_3) };
  500. static const struct snd_kcontrol_new quat_tdm_rx_4_mixer_controls[] = {
  501. Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_4) };
  502. static const struct snd_kcontrol_new quat_tdm_rx_5_mixer_controls[] = {
  503. Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_5) };
  504. static const struct snd_kcontrol_new quat_tdm_rx_6_mixer_controls[] = {
  505. Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_6) };
  506. static const struct snd_kcontrol_new quat_tdm_rx_7_mixer_controls[] = {
  507. Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_7) };
  508. static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = {
  509. Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_0) };
  510. static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = {
  511. Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_1) };
  512. static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = {
  513. Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_2) };
  514. static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = {
  515. Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_3) };
  516. static const struct snd_kcontrol_new quin_tdm_rx_4_mixer_controls[] = {
  517. Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_4) };
  518. static const struct snd_kcontrol_new quin_tdm_rx_5_mixer_controls[] = {
  519. Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_5) };
  520. static const struct snd_kcontrol_new quin_tdm_rx_6_mixer_controls[] = {
  521. Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_6) };
  522. static const struct snd_kcontrol_new quin_tdm_rx_7_mixer_controls[] = {
  523. Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_7) };
  524. static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
  525. Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA1) };
  526. static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
  527. Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA2) };
  528. static const struct snd_kcontrol_new mmul3_mixer_controls[] = {
  529. Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA3) };
  530. static const struct snd_kcontrol_new mmul4_mixer_controls[] = {
  531. Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA4) };
  532. static const struct snd_kcontrol_new mmul5_mixer_controls[] = {
  533. Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA5) };
  534. static const struct snd_kcontrol_new mmul6_mixer_controls[] = {
  535. Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA6) };
  536. static const struct snd_kcontrol_new mmul7_mixer_controls[] = {
  537. Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA7) };
  538. static const struct snd_kcontrol_new mmul8_mixer_controls[] = {
  539. Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA8) };
  540. static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
  541. /* Frontend AIF */
  542. SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
  543. SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
  544. SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
  545. SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
  546. SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0),
  547. SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0),
  548. SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0),
  549. SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0),
  550. SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
  551. SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
  552. SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, 0, 0, 0),
  553. SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0),
  554. SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0),
  555. SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0),
  556. SND_SOC_DAPM_AIF_OUT("MM_UL7", "MultiMedia7 Capture", 0, 0, 0, 0),
  557. SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0),
  558. /* Mixer definitions */
  559. SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
  560. hdmi_mixer_controls,
  561. ARRAY_SIZE(hdmi_mixer_controls)),
  562. SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  563. slimbus_rx_mixer_controls,
  564. ARRAY_SIZE(slimbus_rx_mixer_controls)),
  565. SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  566. slimbus_1_rx_mixer_controls,
  567. ARRAY_SIZE(slimbus_1_rx_mixer_controls)),
  568. SND_SOC_DAPM_MIXER("SLIMBUS_2_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  569. slimbus_2_rx_mixer_controls,
  570. ARRAY_SIZE(slimbus_2_rx_mixer_controls)),
  571. SND_SOC_DAPM_MIXER("SLIMBUS_3_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  572. slimbus_3_rx_mixer_controls,
  573. ARRAY_SIZE(slimbus_3_rx_mixer_controls)),
  574. SND_SOC_DAPM_MIXER("SLIMBUS_4_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  575. slimbus_4_rx_mixer_controls,
  576. ARRAY_SIZE(slimbus_4_rx_mixer_controls)),
  577. SND_SOC_DAPM_MIXER("SLIMBUS_5_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  578. slimbus_5_rx_mixer_controls,
  579. ARRAY_SIZE(slimbus_5_rx_mixer_controls)),
  580. SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  581. slimbus_6_rx_mixer_controls,
  582. ARRAY_SIZE(slimbus_6_rx_mixer_controls)),
  583. SND_SOC_DAPM_MIXER("PRI_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  584. primary_mi2s_rx_mixer_controls,
  585. ARRAY_SIZE(primary_mi2s_rx_mixer_controls)),
  586. SND_SOC_DAPM_MIXER("SEC_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  587. secondary_mi2s_rx_mixer_controls,
  588. ARRAY_SIZE(secondary_mi2s_rx_mixer_controls)),
  589. SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  590. quaternary_mi2s_rx_mixer_controls,
  591. ARRAY_SIZE(quaternary_mi2s_rx_mixer_controls)),
  592. SND_SOC_DAPM_MIXER("TERT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
  593. tertiary_mi2s_rx_mixer_controls,
  594. ARRAY_SIZE(tertiary_mi2s_rx_mixer_controls)),
  595. SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
  596. pri_tdm_rx_0_mixer_controls,
  597. ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)),
  598. SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
  599. pri_tdm_rx_1_mixer_controls,
  600. ARRAY_SIZE(pri_tdm_rx_1_mixer_controls)),
  601. SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
  602. pri_tdm_rx_2_mixer_controls,
  603. ARRAY_SIZE(pri_tdm_rx_2_mixer_controls)),
  604. SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
  605. pri_tdm_rx_3_mixer_controls,
  606. ARRAY_SIZE(pri_tdm_rx_3_mixer_controls)),
  607. SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
  608. pri_tdm_rx_4_mixer_controls,
  609. ARRAY_SIZE(pri_tdm_rx_4_mixer_controls)),
  610. SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
  611. pri_tdm_rx_5_mixer_controls,
  612. ARRAY_SIZE(pri_tdm_rx_5_mixer_controls)),
  613. SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
  614. pri_tdm_rx_6_mixer_controls,
  615. ARRAY_SIZE(pri_tdm_rx_6_mixer_controls)),
  616. SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
  617. pri_tdm_rx_7_mixer_controls,
  618. ARRAY_SIZE(pri_tdm_rx_7_mixer_controls)),
  619. SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
  620. sec_tdm_rx_0_mixer_controls,
  621. ARRAY_SIZE(sec_tdm_rx_0_mixer_controls)),
  622. SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
  623. sec_tdm_rx_1_mixer_controls,
  624. ARRAY_SIZE(sec_tdm_rx_1_mixer_controls)),
  625. SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
  626. sec_tdm_rx_2_mixer_controls,
  627. ARRAY_SIZE(sec_tdm_rx_2_mixer_controls)),
  628. SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
  629. sec_tdm_rx_3_mixer_controls,
  630. ARRAY_SIZE(sec_tdm_rx_3_mixer_controls)),
  631. SND_SOC_DAPM_MIXER("SEC_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
  632. sec_tdm_rx_4_mixer_controls,
  633. ARRAY_SIZE(sec_tdm_rx_4_mixer_controls)),
  634. SND_SOC_DAPM_MIXER("SEC_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
  635. sec_tdm_rx_5_mixer_controls,
  636. ARRAY_SIZE(sec_tdm_rx_5_mixer_controls)),
  637. SND_SOC_DAPM_MIXER("SEC_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
  638. sec_tdm_rx_6_mixer_controls,
  639. ARRAY_SIZE(sec_tdm_rx_6_mixer_controls)),
  640. SND_SOC_DAPM_MIXER("SEC_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
  641. sec_tdm_rx_7_mixer_controls,
  642. ARRAY_SIZE(sec_tdm_rx_7_mixer_controls)),
  643. SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
  644. tert_tdm_rx_0_mixer_controls,
  645. ARRAY_SIZE(tert_tdm_rx_0_mixer_controls)),
  646. SND_SOC_DAPM_MIXER("TERT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
  647. tert_tdm_rx_1_mixer_controls,
  648. ARRAY_SIZE(tert_tdm_rx_1_mixer_controls)),
  649. SND_SOC_DAPM_MIXER("TERT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
  650. tert_tdm_rx_2_mixer_controls,
  651. ARRAY_SIZE(tert_tdm_rx_2_mixer_controls)),
  652. SND_SOC_DAPM_MIXER("TERT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
  653. tert_tdm_rx_3_mixer_controls,
  654. ARRAY_SIZE(tert_tdm_rx_3_mixer_controls)),
  655. SND_SOC_DAPM_MIXER("TERT_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
  656. tert_tdm_rx_4_mixer_controls,
  657. ARRAY_SIZE(tert_tdm_rx_4_mixer_controls)),
  658. SND_SOC_DAPM_MIXER("TERT_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
  659. tert_tdm_rx_5_mixer_controls,
  660. ARRAY_SIZE(tert_tdm_rx_5_mixer_controls)),
  661. SND_SOC_DAPM_MIXER("TERT_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
  662. tert_tdm_rx_6_mixer_controls,
  663. ARRAY_SIZE(tert_tdm_rx_6_mixer_controls)),
  664. SND_SOC_DAPM_MIXER("TERT_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
  665. tert_tdm_rx_7_mixer_controls,
  666. ARRAY_SIZE(tert_tdm_rx_7_mixer_controls)),
  667. SND_SOC_DAPM_MIXER("QUAT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
  668. quat_tdm_rx_0_mixer_controls,
  669. ARRAY_SIZE(quat_tdm_rx_0_mixer_controls)),
  670. SND_SOC_DAPM_MIXER("QUAT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
  671. quat_tdm_rx_1_mixer_controls,
  672. ARRAY_SIZE(quat_tdm_rx_1_mixer_controls)),
  673. SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
  674. quat_tdm_rx_2_mixer_controls,
  675. ARRAY_SIZE(quat_tdm_rx_2_mixer_controls)),
  676. SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
  677. quat_tdm_rx_3_mixer_controls,
  678. ARRAY_SIZE(quat_tdm_rx_3_mixer_controls)),
  679. SND_SOC_DAPM_MIXER("QUAT_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
  680. quat_tdm_rx_4_mixer_controls,
  681. ARRAY_SIZE(quat_tdm_rx_4_mixer_controls)),
  682. SND_SOC_DAPM_MIXER("QUAT_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
  683. quat_tdm_rx_5_mixer_controls,
  684. ARRAY_SIZE(quat_tdm_rx_5_mixer_controls)),
  685. SND_SOC_DAPM_MIXER("QUAT_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
  686. quat_tdm_rx_6_mixer_controls,
  687. ARRAY_SIZE(quat_tdm_rx_6_mixer_controls)),
  688. SND_SOC_DAPM_MIXER("QUAT_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
  689. quat_tdm_rx_7_mixer_controls,
  690. ARRAY_SIZE(quat_tdm_rx_7_mixer_controls)),
  691. SND_SOC_DAPM_MIXER("QUIN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
  692. quin_tdm_rx_0_mixer_controls,
  693. ARRAY_SIZE(quin_tdm_rx_0_mixer_controls)),
  694. SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
  695. quin_tdm_rx_1_mixer_controls,
  696. ARRAY_SIZE(quin_tdm_rx_1_mixer_controls)),
  697. SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
  698. quin_tdm_rx_2_mixer_controls,
  699. ARRAY_SIZE(quin_tdm_rx_2_mixer_controls)),
  700. SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
  701. quin_tdm_rx_3_mixer_controls,
  702. ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)),
  703. SND_SOC_DAPM_MIXER("QUIN_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
  704. quin_tdm_rx_4_mixer_controls,
  705. ARRAY_SIZE(quin_tdm_rx_4_mixer_controls)),
  706. SND_SOC_DAPM_MIXER("QUIN_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
  707. quin_tdm_rx_5_mixer_controls,
  708. ARRAY_SIZE(quin_tdm_rx_5_mixer_controls)),
  709. SND_SOC_DAPM_MIXER("QUIN_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
  710. quin_tdm_rx_6_mixer_controls,
  711. ARRAY_SIZE(quin_tdm_rx_6_mixer_controls)),
  712. SND_SOC_DAPM_MIXER("QUIN_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
  713. quin_tdm_rx_7_mixer_controls,
  714. ARRAY_SIZE(quin_tdm_rx_7_mixer_controls)),
  715. SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
  716. mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
  717. SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
  718. mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
  719. SND_SOC_DAPM_MIXER("MultiMedia3 Mixer", SND_SOC_NOPM, 0, 0,
  720. mmul3_mixer_controls, ARRAY_SIZE(mmul3_mixer_controls)),
  721. SND_SOC_DAPM_MIXER("MultiMedia4 Mixer", SND_SOC_NOPM, 0, 0,
  722. mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)),
  723. SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0,
  724. mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)),
  725. SND_SOC_DAPM_MIXER("MultiMedia6 Mixer", SND_SOC_NOPM, 0, 0,
  726. mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)),
  727. SND_SOC_DAPM_MIXER("MultiMedia7 Mixer", SND_SOC_NOPM, 0, 0,
  728. mmul7_mixer_controls, ARRAY_SIZE(mmul7_mixer_controls)),
  729. SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0,
  730. mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)),
  731. };
  732. static const struct snd_soc_dapm_route intercon[] = {
  733. Q6ROUTING_RX_DAPM_ROUTE("HDMI Mixer", "HDMI_RX"),
  734. Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_0_RX Audio Mixer", "SLIMBUS_0_RX"),
  735. Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_1_RX Audio Mixer", "SLIMBUS_1_RX"),
  736. Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_2_RX Audio Mixer", "SLIMBUS_2_RX"),
  737. Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_3_RX Audio Mixer", "SLIMBUS_3_RX"),
  738. Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_4_RX Audio Mixer", "SLIMBUS_4_RX"),
  739. Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_5_RX Audio Mixer", "SLIMBUS_5_RX"),
  740. Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_6_RX Audio Mixer", "SLIMBUS_6_RX"),
  741. Q6ROUTING_RX_DAPM_ROUTE("QUAT_MI2S_RX Audio Mixer", "QUAT_MI2S_RX"),
  742. Q6ROUTING_RX_DAPM_ROUTE("TERT_MI2S_RX Audio Mixer", "TERT_MI2S_RX"),
  743. Q6ROUTING_RX_DAPM_ROUTE("SEC_MI2S_RX Audio Mixer", "SEC_MI2S_RX"),
  744. Q6ROUTING_RX_DAPM_ROUTE("PRI_MI2S_RX Audio Mixer", "PRI_MI2S_RX"),
  745. Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_0 Audio Mixer",
  746. "PRIMARY_TDM_RX_0"),
  747. Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_1 Audio Mixer",
  748. "PRIMARY_TDM_RX_1"),
  749. Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_2 Audio Mixer",
  750. "PRIMARY_TDM_RX_2"),
  751. Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_3 Audio Mixer",
  752. "PRIMARY_TDM_RX_3"),
  753. Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_4 Audio Mixer",
  754. "PRIMARY_TDM_RX_4"),
  755. Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_5 Audio Mixer",
  756. "PRIMARY_TDM_RX_5"),
  757. Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_6 Audio Mixer",
  758. "PRIMARY_TDM_RX_6"),
  759. Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_7 Audio Mixer",
  760. "PRIMARY_TDM_RX_7"),
  761. Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_0 Audio Mixer", "SEC_TDM_RX_0"),
  762. Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_1 Audio Mixer", "SEC_TDM_RX_1"),
  763. Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_2 Audio Mixer", "SEC_TDM_RX_2"),
  764. Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_3 Audio Mixer", "SEC_TDM_RX_3"),
  765. Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_4 Audio Mixer", "SEC_TDM_RX_4"),
  766. Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_5 Audio Mixer", "SEC_TDM_RX_5"),
  767. Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_6 Audio Mixer", "SEC_TDM_RX_6"),
  768. Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_7 Audio Mixer", "SEC_TDM_RX_7"),
  769. Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_0 Audio Mixer", "TERT_TDM_RX_0"),
  770. Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_1 Audio Mixer", "TERT_TDM_RX_1"),
  771. Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_2 Audio Mixer", "TERT_TDM_RX_2"),
  772. Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_3 Audio Mixer", "TERT_TDM_RX_3"),
  773. Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_4 Audio Mixer", "TERT_TDM_RX_4"),
  774. Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_5 Audio Mixer", "TERT_TDM_RX_5"),
  775. Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_6 Audio Mixer", "TERT_TDM_RX_6"),
  776. Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_7 Audio Mixer", "TERT_TDM_RX_7"),
  777. Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_0 Audio Mixer", "QUAT_TDM_RX_0"),
  778. Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_1 Audio Mixer", "QUAT_TDM_RX_1"),
  779. Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_2 Audio Mixer", "QUAT_TDM_RX_2"),
  780. Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_3 Audio Mixer", "QUAT_TDM_RX_3"),
  781. Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_4 Audio Mixer", "QUAT_TDM_RX_4"),
  782. Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_5 Audio Mixer", "QUAT_TDM_RX_5"),
  783. Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_6 Audio Mixer", "QUAT_TDM_RX_6"),
  784. Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_7 Audio Mixer", "QUAT_TDM_RX_7"),
  785. Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_0 Audio Mixer", "QUIN_TDM_RX_0"),
  786. Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_1 Audio Mixer", "QUIN_TDM_RX_1"),
  787. Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_2 Audio Mixer", "QUIN_TDM_RX_2"),
  788. Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_3 Audio Mixer", "QUIN_TDM_RX_3"),
  789. Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_4 Audio Mixer", "QUIN_TDM_RX_4"),
  790. Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_5 Audio Mixer", "QUIN_TDM_RX_5"),
  791. Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_6 Audio Mixer", "QUIN_TDM_RX_6"),
  792. Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_7 Audio Mixer", "QUIN_TDM_RX_7"),
  793. Q6ROUTING_TX_DAPM_ROUTE("MultiMedia1 Mixer"),
  794. Q6ROUTING_TX_DAPM_ROUTE("MultiMedia2 Mixer"),
  795. Q6ROUTING_TX_DAPM_ROUTE("MultiMedia3 Mixer"),
  796. Q6ROUTING_TX_DAPM_ROUTE("MultiMedia4 Mixer"),
  797. Q6ROUTING_TX_DAPM_ROUTE("MultiMedia5 Mixer"),
  798. Q6ROUTING_TX_DAPM_ROUTE("MultiMedia6 Mixer"),
  799. Q6ROUTING_TX_DAPM_ROUTE("MultiMedia7 Mixer"),
  800. Q6ROUTING_TX_DAPM_ROUTE("MultiMedia8 Mixer"),
  801. {"MM_UL1", NULL, "MultiMedia1 Mixer"},
  802. {"MM_UL2", NULL, "MultiMedia2 Mixer"},
  803. {"MM_UL3", NULL, "MultiMedia3 Mixer"},
  804. {"MM_UL4", NULL, "MultiMedia4 Mixer"},
  805. {"MM_UL5", NULL, "MultiMedia5 Mixer"},
  806. {"MM_UL6", NULL, "MultiMedia6 Mixer"},
  807. {"MM_UL7", NULL, "MultiMedia7 Mixer"},
  808. {"MM_UL8", NULL, "MultiMedia8 Mixer"},
  809. };
  810. static int routing_hw_params(struct snd_pcm_substream *substream,
  811. struct snd_pcm_hw_params *params)
  812. {
  813. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  814. struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
  815. struct msm_routing_data *data = dev_get_drvdata(c->dev);
  816. unsigned int be_id = rtd->cpu_dai->id;
  817. struct session_data *session;
  818. int path_type;
  819. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  820. path_type = ADM_PATH_PLAYBACK;
  821. else
  822. path_type = ADM_PATH_LIVE_REC;
  823. if (be_id >= AFE_MAX_PORTS)
  824. return -EINVAL;
  825. session = &data->port_data[be_id];
  826. mutex_lock(&data->lock);
  827. session->path_type = path_type;
  828. session->sample_rate = params_rate(params);
  829. session->channels = params_channels(params);
  830. switch (params_format(params)) {
  831. case SNDRV_PCM_FORMAT_S16_LE:
  832. session->bits_per_sample = 16;
  833. break;
  834. case SNDRV_PCM_FORMAT_S24_LE:
  835. session->bits_per_sample = 24;
  836. break;
  837. default:
  838. break;
  839. }
  840. mutex_unlock(&data->lock);
  841. return 0;
  842. }
  843. static struct snd_pcm_ops q6pcm_routing_ops = {
  844. .hw_params = routing_hw_params,
  845. };
  846. static int msm_routing_probe(struct snd_soc_component *c)
  847. {
  848. int i;
  849. for (i = 0; i < MAX_SESSIONS; i++) {
  850. routing_data->sessions[i].port_id = -1;
  851. routing_data->sessions[i].fedai_id = -1;
  852. }
  853. return 0;
  854. }
  855. static unsigned int q6routing_reg_read(struct snd_soc_component *component,
  856. unsigned int reg)
  857. {
  858. /* default value */
  859. return 0;
  860. }
  861. static int q6routing_reg_write(struct snd_soc_component *component,
  862. unsigned int reg, unsigned int val)
  863. {
  864. /* dummy */
  865. return 0;
  866. }
  867. static const struct snd_soc_component_driver msm_soc_routing_component = {
  868. .ops = &q6pcm_routing_ops,
  869. .probe = msm_routing_probe,
  870. .name = DRV_NAME,
  871. .dapm_widgets = msm_qdsp6_widgets,
  872. .num_dapm_widgets = ARRAY_SIZE(msm_qdsp6_widgets),
  873. .dapm_routes = intercon,
  874. .num_dapm_routes = ARRAY_SIZE(intercon),
  875. .read = q6routing_reg_read,
  876. .write = q6routing_reg_write,
  877. };
  878. static int q6pcm_routing_probe(struct platform_device *pdev)
  879. {
  880. struct device *dev = &pdev->dev;
  881. routing_data = kzalloc(sizeof(*routing_data), GFP_KERNEL);
  882. if (!routing_data)
  883. return -ENOMEM;
  884. routing_data->dev = dev;
  885. mutex_init(&routing_data->lock);
  886. dev_set_drvdata(dev, routing_data);
  887. return devm_snd_soc_register_component(dev, &msm_soc_routing_component,
  888. NULL, 0);
  889. }
  890. static int q6pcm_routing_remove(struct platform_device *pdev)
  891. {
  892. kfree(routing_data);
  893. routing_data = NULL;
  894. return 0;
  895. }
  896. static const struct of_device_id q6pcm_routing_device_id[] = {
  897. { .compatible = "qcom,q6adm-routing" },
  898. {},
  899. };
  900. MODULE_DEVICE_TABLE(of, q6pcm_routing_device_id);
  901. static struct platform_driver q6pcm_routing_platform_driver = {
  902. .driver = {
  903. .name = "q6routing",
  904. .of_match_table = of_match_ptr(q6pcm_routing_device_id),
  905. },
  906. .probe = q6pcm_routing_probe,
  907. .remove = q6pcm_routing_remove,
  908. };
  909. module_platform_driver(q6pcm_routing_platform_driver);
  910. MODULE_DESCRIPTION("Q6 Routing platform");
  911. MODULE_LICENSE("GPL v2");