btfm_codec_interface.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/remoteproc.h>
  7. #include <linux/remoteproc/qcom_rproc.h>
  8. #include "btfm_codec.h"
  9. #include "btfm_codec_interface.h"
  10. #include "btfm_codec_pkt.h"
  11. #include "btfm_codec_btadv_interface.h"
  12. static struct snd_soc_dai_driver *btfmcodec_dai_info;
  13. uint32_t bits_per_second;
  14. uint8_t num_channels;
  15. static int btfm_codec_get_mixer_control(struct snd_kcontrol *kcontrol,
  16. struct snd_ctl_elem_value *ucontrol)
  17. {
  18. struct snd_soc_component *codec = kcontrol->private_data;
  19. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(codec);
  20. struct hwep_data *hwepinfo = btfmcodec->hwep_info;
  21. struct snd_kcontrol_new *mixer_ctrl = hwepinfo->mixer_ctrl;
  22. struct snd_ctl_elem_id id = kcontrol->id;
  23. int num_mixer_ctrl = hwepinfo->num_mixer_ctrl;
  24. int i = 0;
  25. BTFMCODEC_DBG("");
  26. for (; i < num_mixer_ctrl ; i++) {
  27. BTFMCODEC_DBG("checking mixer_ctrl:%s and current mixer:%s",
  28. id.name, mixer_ctrl[i].name);
  29. if (!strncmp(id.name, mixer_ctrl[i].name, 64)) {
  30. BTFMCODEC_DBG("Matched");
  31. mixer_ctrl[i].get(kcontrol, ucontrol);
  32. break;
  33. }
  34. }
  35. if (num_mixer_ctrl == i)
  36. return 0;
  37. return 1;
  38. }
  39. static int btfmcodec_put_mixer_control(struct snd_kcontrol *kcontrol,
  40. struct snd_ctl_elem_value *ucontrol)
  41. {
  42. struct snd_soc_component *codec = kcontrol->private_data;
  43. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(codec);
  44. struct hwep_data *hwepinfo = btfmcodec->hwep_info;
  45. struct snd_kcontrol_new *mixer_ctrl = hwepinfo->mixer_ctrl;
  46. struct snd_ctl_elem_id id = kcontrol->id;
  47. int num_mixer_ctrl = hwepinfo->num_mixer_ctrl;
  48. int i = 0;
  49. BTFMCODEC_DBG("");
  50. for (; i < num_mixer_ctrl ; i++) {
  51. BTFMCODEC_DBG("checking mixer_ctrl:%s and current mixer:%s",
  52. id.name, mixer_ctrl[i].name);
  53. if (!strncmp(id.name, mixer_ctrl[i].name, 64)) {
  54. BTFMCODEC_DBG("Matched");
  55. mixer_ctrl[i].put(kcontrol, ucontrol);
  56. break;
  57. }
  58. }
  59. if (num_mixer_ctrl == i)
  60. return 0;
  61. return 1;
  62. }
  63. static int btfmcodec_codec_probe(struct snd_soc_component *codec)
  64. {
  65. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(codec);
  66. struct btfmcodec_state_machine *state = &btfmcodec->states;
  67. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  68. int num_mixer_ctrl = hwep_info->num_mixer_ctrl;
  69. BTFMCODEC_DBG("");
  70. // ToDo: check Whether probe has to allowed when state if different
  71. if (btfmcodec_get_current_transport(state)!= IDLE) {
  72. BTFMCODEC_WARN("Received probe when state is :%s",
  73. coverttostring(btfmcodec_get_current_transport(state)));
  74. } else if (hwep_info->drv && hwep_info->drv->hwep_probe) {
  75. hwep_info->drv->hwep_probe(codec);
  76. /* Register mixer control */
  77. if (hwep_info->mixer_ctrl && num_mixer_ctrl >= 1) {
  78. struct snd_kcontrol_new *mixer_ctrl;
  79. int i = 0;
  80. mixer_ctrl = (struct snd_kcontrol_new *)
  81. kzalloc(num_mixer_ctrl *
  82. sizeof(struct snd_kcontrol_new), GFP_KERNEL);
  83. if (!mixer_ctrl) {
  84. BTFMCODEC_ERR("failed to register mixer controls");
  85. goto end;
  86. }
  87. BTFMCODEC_INFO("Registering %d mixer controls", num_mixer_ctrl);
  88. memcpy(mixer_ctrl, hwep_info->mixer_ctrl, num_mixer_ctrl * sizeof(struct snd_kcontrol_new));
  89. for (; i< num_mixer_ctrl; i++) {
  90. BTFMCODEC_INFO("name of control:%s", mixer_ctrl[i].name);
  91. mixer_ctrl[i].get = btfm_codec_get_mixer_control;
  92. mixer_ctrl[i].put = btfmcodec_put_mixer_control;
  93. }
  94. snd_soc_add_component_controls(codec, mixer_ctrl, num_mixer_ctrl);
  95. BTFMCODEC_INFO("CODEC address while registering mixer ctrl:%p", codec);
  96. }
  97. }
  98. end:
  99. // ToDo to add mixer control.
  100. return 0;
  101. }
  102. static void btfmcodec_codec_remove(struct snd_soc_component *codec)
  103. {
  104. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(codec);
  105. struct btfmcodec_state_machine *state = &btfmcodec->states;
  106. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  107. BTFMCODEC_DBG("");
  108. // ToDo: check whether remove has to allowed when state if different
  109. if (btfmcodec_get_current_transport(state)!= IDLE) {
  110. BTFMCODEC_WARN("Received probe when state is :%s",
  111. coverttostring(btfmcodec_get_current_transport(state)));
  112. } else if (hwep_info->drv && hwep_info->drv->hwep_remove) {
  113. hwep_info->drv->hwep_remove(codec);
  114. }
  115. }
  116. static int btfmcodec_codec_write(struct snd_soc_component *codec,
  117. unsigned int reg, unsigned int value)
  118. {
  119. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(codec);
  120. struct btfmcodec_state_machine *state = &btfmcodec->states;
  121. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  122. BTFMCODEC_DBG("");
  123. // ToDo: check whether write has to allowed when state if different
  124. if (btfmcodec_get_current_transport(state)!= IDLE) {
  125. BTFMCODEC_WARN("Received probe when state is :%s",
  126. coverttostring(btfmcodec_get_current_transport(state)));
  127. } else if (hwep_info->drv && hwep_info->drv->hwep_remove) {
  128. return hwep_info->drv->hwep_write(codec, reg, value);
  129. }
  130. return 0;
  131. }
  132. static unsigned int btfmcodec_codec_read(struct snd_soc_component *codec,
  133. unsigned int reg)
  134. {
  135. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(codec);
  136. struct btfmcodec_state_machine *state = &btfmcodec->states;
  137. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  138. BTFMCODEC_DBG("");
  139. // ToDo: check whether read has to allowed when state if different
  140. if (btfmcodec_get_current_transport(state)!= IDLE) {
  141. BTFMCODEC_WARN("Received probe when state is :%s",
  142. coverttostring(btfmcodec_get_current_transport(state)));
  143. } else if (hwep_info->drv && hwep_info->drv->hwep_read) {
  144. return hwep_info->drv->hwep_read(codec, reg);
  145. }
  146. return 0;
  147. }
  148. static const struct snd_soc_component_driver btfmcodec_codec_component = {
  149. .probe = btfmcodec_codec_probe,
  150. .remove = btfmcodec_codec_remove,
  151. .read = btfmcodec_codec_read,
  152. .write = btfmcodec_codec_write,
  153. };
  154. static inline void * btfmcodec_get_dai_drvdata(struct hwep_data *hwep_info)
  155. {
  156. if (!hwep_info || !hwep_info->dai_drv) return NULL;
  157. return hwep_info->dai_drv;
  158. }
  159. int btfmcodec_hwep_startup(struct btfmcodec_data *btfmcodec)
  160. {
  161. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  162. struct hwep_dai_driver *dai_drv = (struct hwep_dai_driver *)
  163. btfmcodec_get_dai_drvdata(hwep_info);
  164. if (dai_drv && dai_drv->dai_ops && dai_drv->dai_ops->hwep_startup) {
  165. return dai_drv->dai_ops->hwep_startup((void *)btfmcodec->hwep_info);
  166. } else {
  167. return -1;
  168. }
  169. }
  170. static int btfmcodec_dai_startup(struct snd_pcm_substream *substream,
  171. struct snd_soc_dai *dai)
  172. {
  173. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(dai->component);
  174. struct btfmcodec_state_machine *state = &btfmcodec->states;
  175. BTFMCODEC_DBG("substream = %s stream = %d dai->name = %s",
  176. substream->name, substream->stream, dai->name);
  177. if (btfmcodec_get_current_transport(state) != IDLE &&
  178. btfmcodec_get_current_transport(state) != BT_Connected) {
  179. BTFMCODEC_DBG("Not allowing as state is:%s",
  180. coverttostring(btfmcodec_get_current_transport(state)));
  181. } else {
  182. return btfmcodec_hwep_startup(btfmcodec);
  183. }
  184. return 0;
  185. }
  186. int btfmcodec_hwep_shutdown(struct btfmcodec_data *btfmcodec, int id,
  187. bool disable_master)
  188. {
  189. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  190. struct btfmcodec_char_device *btfmcodec_dev = btfmcodec->btfmcodec_dev;
  191. struct hwep_dai_driver *dai_drv = (struct hwep_dai_driver *)
  192. btfmcodec_get_dai_drvdata(hwep_info);
  193. struct btfmcodec_state_machine *state = &btfmcodec->states;
  194. struct btm_master_shutdown_req shutdown_req;
  195. wait_queue_head_t *rsp_wait_q =
  196. &btfmcodec_dev->rsp_wait_q[BTM_PKT_TYPE_MASTER_SHUTDOWN_RSP];
  197. uint8_t *status = &btfmcodec_dev->status[BTM_PKT_TYPE_MASTER_SHUTDOWN_RSP];
  198. int ret = 0;
  199. /* for master configurations failure cases, we don't need to send
  200. * shutdown request
  201. */
  202. if (btfmcodec_get_current_transport(state) == BT_Connected && disable_master) {
  203. BTFMCODEC_DBG("sending master shutdown request..");
  204. shutdown_req.opcode = BTM_BTFMCODEC_MASTER_SHUTDOWN_REQ;
  205. shutdown_req.len = BTM_MASTER_SHUTDOWN_REQ_LEN;
  206. shutdown_req.stream_id = id;
  207. /* See if we need to protect below with lock */
  208. *status = BTM_WAITING_RSP;
  209. btfmcodec_dev_enqueue_pkt(btfmcodec_dev, &shutdown_req, (shutdown_req.len +
  210. BTM_HEADER_LEN));
  211. ret = wait_event_interruptible_timeout(*rsp_wait_q,
  212. (*status) != BTM_WAITING_RSP,
  213. msecs_to_jiffies(BTM_MASTER_CONFIG_RSP_TIMEOUT));
  214. if (ret == 0) {
  215. BTFMCODEC_ERR("failed to recevie response from BTADV audio Manager");
  216. } else {
  217. if (*status == BTM_RSP_RECV)
  218. ret = 0;
  219. else if (*status == BTM_FAIL_RESP_RECV ||
  220. *status == BTM_RSP_NOT_RECV_CLIENT_KILLED)
  221. ret = -1;
  222. }
  223. } else {
  224. if (!disable_master)
  225. BTFMCODEC_WARN("Not sending master shutdown request as graph might have closed");
  226. else
  227. BTFMCODEC_WARN("Not sending master shutdown request as state is:%s",
  228. coverttostring(btfmcodec_get_current_transport(state)));
  229. }
  230. if (dai_drv && dai_drv->dai_ops && dai_drv->dai_ops->hwep_shutdown) {
  231. dai_drv->dai_ops->hwep_shutdown((void *)btfmcodec->hwep_info, id);
  232. }
  233. return ret;
  234. }
  235. void btfmcodec_wq_hwep_shutdown(struct work_struct *work)
  236. {
  237. struct btfmcodec_char_device *btfmcodec_dev = container_of(work,
  238. struct btfmcodec_char_device,
  239. wq_hwep_shutdown);
  240. struct btfmcodec_data *btfmcodec = (struct btfmcodec_data *)btfmcodec_dev->btfmcodec;
  241. struct list_head *head = &btfmcodec->config_head;
  242. struct hwep_configurations *hwep_configs = NULL, *tmp;
  243. int ret = -1;
  244. int idx = BTM_PKT_TYPE_HWEP_SHUTDOWN;
  245. BTFMCODEC_INFO(" starting shutdown");
  246. /* Just check if first Rx has to be closed first or
  247. * any order should be ok.
  248. */
  249. list_for_each_entry_safe(hwep_configs, tmp, head, dai_list) {
  250. BTFMCODEC_INFO("shuting down dai id:%d", hwep_configs->stream_id);
  251. ret = btfmcodec_hwep_shutdown(btfmcodec, hwep_configs->stream_id, true);
  252. if (ret < 0) {
  253. BTFMCODEC_ERR("failed to shutdown master with id %d", hwep_configs->stream_id);
  254. break;
  255. }
  256. }
  257. if (ret < 0)
  258. btfmcodec_dev->status[idx] = BTM_FAIL_RESP_RECV;
  259. else
  260. btfmcodec_dev->status[idx] = BTM_RSP_RECV;
  261. wake_up_interruptible(&btfmcodec_dev->rsp_wait_q[idx]);
  262. }
  263. static int btfmcodec_delete_configs(struct btfmcodec_data *btfmcodec, uint8_t id)
  264. {
  265. struct list_head *head = &btfmcodec->config_head;
  266. struct hwep_configurations *hwep_configs, *tmp;
  267. int ret = -1;
  268. list_for_each_entry_safe(hwep_configs, tmp, head, dai_list) {
  269. if (hwep_configs->stream_id == id) {
  270. BTFMCODEC_INFO("deleting configs with id %d", id);
  271. list_del(&hwep_configs->dai_list);
  272. ret = 1;
  273. break;
  274. }
  275. }
  276. return ret;
  277. }
  278. static void btfmcodec_dai_shutdown(struct snd_pcm_substream *substream,
  279. struct snd_soc_dai *dai)
  280. {
  281. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(dai->component);
  282. struct btfmcodec_state_machine *state = &btfmcodec->states;
  283. BTFMCODEC_DBG("dai->name: %s, dai->id: %d, dai->rate: %d", dai->name,
  284. dai->id, dai->rate);
  285. if (btfmcodec_get_current_transport(state) != IDLE &&
  286. btfmcodec_get_current_transport(state) != BT_Connected) {
  287. BTFMCODEC_WARN("not allowing shutdown as state is:%s",
  288. coverttostring(btfmcodec_get_current_transport(state)));
  289. /* Delete stored configs */
  290. btfmcodec_delete_configs(btfmcodec, dai->id);
  291. } else {
  292. /* first master shutdown has to done */
  293. btfmcodec_hwep_shutdown(btfmcodec, dai->id, false);
  294. btfmcodec_delete_configs(btfmcodec, dai->id);
  295. if (!btfmcodec_is_valid_cache_avb(btfmcodec))
  296. btfmcodec_set_current_state(state, IDLE);
  297. else {
  298. BTFMCODEC_WARN("valid stream id is available not updating state\n");
  299. btfmcodec_set_current_state(state, BT_Connected);
  300. }
  301. }
  302. }
  303. int btfmcodec_hwep_hw_params (struct btfmcodec_data *btfmcodec, uint32_t bps,
  304. uint32_t direction, uint8_t num_channels)
  305. {
  306. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  307. struct hwep_dai_driver *dai_drv = (struct hwep_dai_driver *)
  308. btfmcodec_get_dai_drvdata(hwep_info);
  309. if (dai_drv && dai_drv->dai_ops && dai_drv->dai_ops->hwep_hw_params) {
  310. return dai_drv->dai_ops->hwep_hw_params((void *)btfmcodec->hwep_info,
  311. bps, direction,
  312. num_channels);
  313. } else {
  314. return -1;
  315. }
  316. }
  317. static int btfmcodec_dai_hw_params(struct snd_pcm_substream *substream,
  318. struct snd_pcm_hw_params *params,
  319. struct snd_soc_dai *dai)
  320. {
  321. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(dai->component);
  322. struct btfmcodec_state_machine *state = &btfmcodec->states;
  323. uint32_t direction = substream->stream;
  324. BTFMCODEC_DBG("dai->name = %s DAI-ID %x rate %d bps %d num_ch %d",
  325. dai->name, dai->id, params_rate(params), params_width(params),
  326. params_channels(params));
  327. bits_per_second = params_width(params);
  328. num_channels = params_channels(params);
  329. if (btfmcodec_get_current_transport(state) != IDLE &&
  330. btfmcodec_get_current_transport(state) != BT_Connected) {
  331. BTFMCODEC_WARN("caching bps and num_channels as state is :%s",
  332. coverttostring(btfmcodec_get_current_transport(state)));
  333. } else {
  334. return btfmcodec_hwep_hw_params(btfmcodec, bits_per_second,
  335. direction, num_channels);
  336. }
  337. return 0;
  338. }
  339. bool btfmcodec_is_valid_cache_avb(struct btfmcodec_data *btfmcodec)
  340. {
  341. struct list_head *head = &btfmcodec->config_head;
  342. struct hwep_configurations *hwep_configs, *tmp;
  343. bool cache_avb = false;
  344. list_for_each_entry_safe(hwep_configs, tmp, head, dai_list) {
  345. cache_avb = true;
  346. break;
  347. }
  348. return cache_avb;
  349. }
  350. static int btfmcodec_check_and_cache_configs(struct btfmcodec_data *btfmcodec,
  351. uint32_t sampling_rate, uint32_t direction,
  352. int id, uint8_t codectype)
  353. {
  354. struct list_head *head = &btfmcodec->config_head;
  355. struct hwep_configurations *hwep_configs, *tmp;
  356. list_for_each_entry_safe(hwep_configs, tmp, head, dai_list) {
  357. if (hwep_configs->stream_id == id) {
  358. BTFMCODEC_WARN("previous entry for %d is already available",
  359. id);
  360. list_del(&hwep_configs->dai_list);
  361. }
  362. }
  363. hwep_configs = kzalloc(sizeof(struct hwep_configurations),
  364. GFP_KERNEL);
  365. if (!hwep_configs) {
  366. BTFMCODEC_ERR("failed to allocate memory");
  367. return -ENOMEM;
  368. }
  369. hwep_configs->stream_id = id; /* Stream identifier */
  370. hwep_configs->sample_rate = sampling_rate;
  371. hwep_configs->bit_width = bits_per_second;
  372. hwep_configs->codectype = codectype;
  373. hwep_configs->direction = direction;
  374. hwep_configs->num_channels = num_channels;
  375. list_add(&hwep_configs->dai_list, head);
  376. BTFMCODEC_INFO("added dai id:%d to list with sampling_rate :%u, direction:%u", id, sampling_rate, direction);
  377. return 1;
  378. }
  379. static int btfmcodec_configure_master(struct btfmcodec_data *btfmcodec, uint8_t id)
  380. {
  381. struct btfmcodec_char_device *btfmcodec_dev = btfmcodec->btfmcodec_dev;
  382. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  383. struct master_hwep_configurations hwep_configs;
  384. struct btm_master_config_req config_req;
  385. struct hwep_dai_driver *dai_drv = (struct hwep_dai_driver *)
  386. btfmcodec_get_dai_drvdata(hwep_info);
  387. wait_queue_head_t *rsp_wait_q =
  388. &btfmcodec_dev->rsp_wait_q[BTM_PKT_TYPE_MASTER_CONFIG_RSP];
  389. uint8_t *status = &btfmcodec_dev->status[BTM_PKT_TYPE_MASTER_CONFIG_RSP];
  390. int ret = 0;
  391. if (dai_drv && dai_drv->dai_ops && dai_drv->dai_ops->hwep_get_configs) {
  392. dai_drv->dai_ops->hwep_get_configs((void *)btfmcodec->hwep_info,
  393. &hwep_configs, id);
  394. } else {
  395. BTFMCODEC_ERR("No hwep_get_configs is set by hw ep driver");
  396. return -1;
  397. }
  398. BTFMCODEC_INFO("framing packet for %d", id);
  399. config_req.opcode = BTM_BTFMCODEC_MASTER_CONFIG_REQ;
  400. config_req.len = BTM_MASTER_CONFIG_REQ_LEN;
  401. config_req.stream_id = hwep_configs.stream_id;
  402. config_req.device_id = hwep_configs.device_id;
  403. config_req.sample_rate = hwep_configs.sample_rate;
  404. config_req.bit_width = hwep_configs.bit_width;
  405. config_req.num_channels = hwep_configs.num_channels;
  406. config_req.channel_num = hwep_configs.chan_num;
  407. config_req.codec_id = hwep_configs.codectype;
  408. BTFMCODEC_DBG("================================================\n");
  409. BTFMCODEC_DBG("dma_config_req.len :%d", config_req.len);
  410. BTFMCODEC_DBG("dma_config_req.stream_id :%d", config_req.stream_id);
  411. BTFMCODEC_DBG("dma_config_req.device_id :%d", config_req.device_id);
  412. BTFMCODEC_DBG("dma_config_req.sample_rate :%d", config_req.sample_rate);
  413. BTFMCODEC_DBG("dma_config_req.bit_width :%d", config_req.bit_width);
  414. BTFMCODEC_DBG("dma_config_req.num_channels :%d", config_req.num_channels);
  415. BTFMCODEC_DBG("dma_config_req.channel_num :%d", config_req.channel_num);
  416. BTFMCODEC_DBG("dma_config_req.codec_id :%d", config_req.codec_id);
  417. BTFMCODEC_DBG("================================================\n");
  418. /* See if we need to protect below with lock */
  419. *status = BTM_WAITING_RSP;
  420. btfmcodec_dev_enqueue_pkt(btfmcodec_dev, &config_req, (config_req.len +
  421. BTM_HEADER_LEN));
  422. ret = wait_event_interruptible_timeout(*rsp_wait_q,
  423. (*status) != BTM_WAITING_RSP,
  424. msecs_to_jiffies(BTM_MASTER_CONFIG_RSP_TIMEOUT));
  425. if (ret == 0) {
  426. BTFMCODEC_ERR("failed to recevie response from BTADV audio Manager");
  427. ret = -ETIMEDOUT;
  428. } else {
  429. if (*status == BTM_RSP_RECV)
  430. return 0;
  431. else if (*status == BTM_FAIL_RESP_RECV ||
  432. *status == BTM_RSP_NOT_RECV_CLIENT_KILLED)
  433. return -1;
  434. }
  435. return ret;
  436. }
  437. static int btfmcodec_configure_dma(struct btfmcodec_data *btfmcodec, uint8_t id)
  438. {
  439. struct btfmcodec_char_device *btfmcodec_dev = btfmcodec->btfmcodec_dev;
  440. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  441. struct hwep_dma_configurations dma_config;
  442. struct btm_dma_config_req dma_config_req;
  443. struct hwep_dai_driver *dai_drv = (struct hwep_dai_driver *)
  444. btfmcodec_get_dai_drvdata(hwep_info);
  445. wait_queue_head_t *rsp_wait_q =
  446. &btfmcodec_dev->rsp_wait_q[BTM_PKT_TYPE_DMA_CONFIG_RSP];
  447. uint8_t *status = &btfmcodec_dev->status[BTM_PKT_TYPE_DMA_CONFIG_RSP];
  448. int ret = 0;
  449. if (dai_drv && dai_drv->dai_ops && dai_drv->dai_ops->hwep_get_configs) {
  450. dai_drv->dai_ops->hwep_get_configs((void *)btfmcodec->hwep_info,
  451. &dma_config, id);
  452. } else {
  453. BTFMCODEC_ERR("No hwep_get_configs is set by hw ep driver");
  454. return -1;
  455. }
  456. BTFMCODEC_INFO("framing packet for %d", id);
  457. dma_config_req.opcode = BTM_BTFMCODEC_CODEC_CONFIG_DMA_REQ;
  458. dma_config_req.len = BTM_CODEC_CONFIG_DMA_REQ_LEN;
  459. dma_config_req.stream_id = dma_config.stream_id;
  460. dma_config_req.sample_rate = dma_config.sample_rate;
  461. dma_config_req.bit_width = dma_config.bit_width;
  462. dma_config_req.num_channels = dma_config.num_channels;
  463. dma_config_req.codec_id = dma_config.codectype;
  464. dma_config_req.lpaif = dma_config.lpaif;
  465. dma_config_req.inf_index = dma_config.inf_index;
  466. dma_config_req.active_channel_mask = dma_config.active_channel_mask;
  467. BTFMCODEC_DBG("================================================\n");
  468. BTFMCODEC_DBG("dma_config_req.len :%d", dma_config_req.len);
  469. BTFMCODEC_DBG("dma_config_req.stream_id :%d", dma_config_req.stream_id);
  470. BTFMCODEC_DBG("dma_config_req.sample_rate :%d", dma_config_req.sample_rate);
  471. BTFMCODEC_DBG("dma_config_req.bit_width :%d", dma_config_req.bit_width);
  472. BTFMCODEC_DBG("dma_config_req.num_channels :%d", dma_config_req.num_channels);
  473. BTFMCODEC_DBG("dma_config_req.codec_id :%d", dma_config_req.codec_id);
  474. BTFMCODEC_DBG("dma_config_req.lpaif :%d", dma_config_req.lpaif);
  475. BTFMCODEC_DBG("dma_config_req.inf_index :%d", dma_config_req.inf_index);
  476. BTFMCODEC_DBG("dma_config_req.active_channel_mask :%d", dma_config_req.active_channel_mask);
  477. BTFMCODEC_DBG("================================================\n");
  478. *status = BTM_WAITING_RSP;
  479. btfmcodec_dev_enqueue_pkt(btfmcodec_dev, &dma_config_req, (dma_config_req.len +
  480. BTM_HEADER_LEN));
  481. ret = wait_event_interruptible_timeout(*rsp_wait_q,
  482. (*status) != BTM_WAITING_RSP,
  483. msecs_to_jiffies(BTM_MASTER_DMA_CONFIG_RSP_TIMEOUT));
  484. if (ret == 0) {
  485. BTFMCODEC_ERR("failed to recevie response from BTADV audio Manager");
  486. ret = -ETIMEDOUT;
  487. } else {
  488. if (*status == BTM_RSP_RECV)
  489. return 0;
  490. else if (*status == BTM_FAIL_RESP_RECV ||
  491. *status == BTM_RSP_NOT_RECV_CLIENT_KILLED)
  492. return -1;
  493. }
  494. return ret;
  495. }
  496. int btfmcodec_hwep_prepare(struct btfmcodec_data *btfmcodec, uint32_t sampling_rate,
  497. uint32_t direction, int id)
  498. {
  499. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  500. struct hwep_dai_driver *dai_drv = (struct hwep_dai_driver *)
  501. btfmcodec_get_dai_drvdata(hwep_info);
  502. struct btfmcodec_state_machine *state = &btfmcodec->states;
  503. int ret;
  504. if (dai_drv && dai_drv->dai_ops && dai_drv->dai_ops->hwep_prepare) {
  505. ret = dai_drv->dai_ops->hwep_prepare((void *)hwep_info, sampling_rate,
  506. direction, id);
  507. BTFMCODEC_ERR("%s: hwep info %d", __func__, hwep_info->flags);
  508. if (ret == 0 && test_bit(BTADV_AUDIO_MASTER_CONFIG, &hwep_info->flags)) {
  509. ret = btfmcodec_configure_master(btfmcodec, (uint8_t)id);
  510. if (ret < 0) {
  511. BTFMCODEC_ERR("failed to configure master error %d", ret);
  512. btfmcodec_set_current_state(state, IDLE);
  513. } else {
  514. btfmcodec_set_current_state(state, BT_Connected);
  515. }
  516. } else if (ret == 0 && test_bit(BTADV_CONFIGURE_DMA, &hwep_info->flags)) {
  517. ret = btfmcodec_configure_dma(btfmcodec, (uint8_t)id);
  518. if (ret < 0) {
  519. BTFMCODEC_ERR("failed to configure Codec DMA %d", ret);
  520. btfmcodec_set_current_state(state, IDLE);
  521. } else {
  522. btfmcodec_set_current_state(state, BT_Connected);
  523. }
  524. }
  525. } else {
  526. return -1;
  527. }
  528. return ret;
  529. }
  530. static int btfmcodec_notify_usecase_start(struct btfmcodec_data *btfmcodec,
  531. uint8_t transport)
  532. {
  533. struct btfmcodec_char_device *btfmcodec_dev = btfmcodec->btfmcodec_dev;
  534. struct btm_usecase_start_ind ind;
  535. ind.opcode = BTM_BTFMCODEC_USECASE_START_IND;
  536. ind.len = BTM_USECASE_START_IND_LEN;
  537. ind.transport = transport;
  538. return btfmcodec_dev_enqueue_pkt(btfmcodec_dev, &ind, (ind.len +
  539. BTM_HEADER_LEN));
  540. }
  541. static int btfmcodec_dai_prepare(struct snd_pcm_substream *substream,
  542. struct snd_soc_dai *dai)
  543. {
  544. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(dai->component);
  545. struct btfmcodec_state_machine *state = &btfmcodec->states;
  546. struct hwep_data *hwep_info = btfmcodec->hwep_info;
  547. struct hwep_dai_driver *dai_drv = (struct hwep_dai_driver *)
  548. btfmcodec_get_dai_drvdata(hwep_info);
  549. uint8_t *codectype = dai_drv->dai_ops->hwep_codectype;
  550. uint32_t sampling_rate = dai->rate;
  551. uint32_t direction = substream->stream;
  552. int id = dai->id;
  553. int ret ;
  554. BTFMCODEC_INFO("dai->name: %s, dai->id: %d, dai->rate: %d direction: %d",
  555. dai->name, id, sampling_rate, direction);
  556. ret = btfmcodec_check_and_cache_configs(btfmcodec, sampling_rate,
  557. direction, id, *codectype);
  558. if (btfmcodec_get_current_transport(state) != IDLE &&
  559. btfmcodec_get_current_transport(state) != BT_Connected) {
  560. BTFMCODEC_WARN("cached required info as state is:%s",
  561. coverttostring(btfmcodec_get_current_transport(state)));
  562. btfmcodec_notify_usecase_start(btfmcodec, BTADV);
  563. } else {
  564. ret = btfmcodec_hwep_prepare(btfmcodec, sampling_rate, direction, id);
  565. /* if (ret >= 0) {
  566. btfmcodec_check_and_cache_configs(btfmcodec, sampling_rate, direction,
  567. id, *codectype);
  568. }
  569. */ }
  570. return ret;
  571. }
  572. int btfmcodec_hwep_set_channel_map(void *hwep_info, unsigned int tx_num,
  573. unsigned int *tx_slot, unsigned int rx_num,
  574. unsigned int *rx_slot)
  575. {
  576. struct hwep_dai_driver *dai_drv = (struct hwep_dai_driver *)
  577. btfmcodec_get_dai_drvdata(hwep_info);
  578. if (dai_drv && dai_drv->dai_ops && dai_drv->dai_ops->hwep_set_channel_map) {
  579. return dai_drv->dai_ops->hwep_set_channel_map(hwep_info, tx_num,
  580. tx_slot, rx_num,
  581. rx_slot);
  582. } else {
  583. return -1;
  584. }
  585. }
  586. static int btfmcodec_dai_set_channel_map(struct snd_soc_dai *dai,
  587. unsigned int tx_num, unsigned int *tx_slot,
  588. unsigned int rx_num, unsigned int *rx_slot)
  589. {
  590. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(dai->component);
  591. struct btfmcodec_state_machine states = btfmcodec->states;
  592. BTFMCODEC_DBG("");
  593. // ToDo: check whether hw_params has to allowed when state if different
  594. if (states.current_state != IDLE) {
  595. BTFMCODEC_WARN("Received probe when state is :%s", coverttostring(states.current_state));
  596. } else {
  597. return btfmcodec_hwep_set_channel_map((void *)btfmcodec->hwep_info, tx_num,
  598. tx_slot, rx_num, rx_slot);
  599. }
  600. return 0;
  601. }
  602. int btfmcodec_hwep_get_channel_map(void *hwep_info, unsigned int *tx_num,
  603. unsigned int *tx_slot, unsigned int *rx_num,
  604. unsigned int *rx_slot, int id)
  605. {
  606. struct hwep_dai_driver *dai_drv = (struct hwep_dai_driver *)
  607. btfmcodec_get_dai_drvdata(hwep_info);
  608. if (dai_drv && dai_drv->dai_ops && dai_drv->dai_ops->hwep_get_channel_map) {
  609. return dai_drv->dai_ops->hwep_get_channel_map(hwep_info, tx_num,
  610. tx_slot, rx_num,
  611. rx_slot, id);
  612. } else {
  613. return -1;
  614. }
  615. }
  616. static int btfmcodec_dai_get_channel_map(struct snd_soc_dai *dai,
  617. unsigned int *tx_num, unsigned int *tx_slot,
  618. unsigned int *rx_num, unsigned int *rx_slot)
  619. {
  620. struct btfmcodec_data *btfmcodec = snd_soc_component_get_drvdata(dai->component);
  621. // struct btfmcodec_state_machine states = btfmcodec->states;
  622. BTFMCODEC_DBG("");
  623. // ToDo: get_channel_map is not needed for new driver
  624. /* if (states.current_state != IDLE) {
  625. BTFMCODEC_WARN("Received probe when state is :%s", coverttostring(states.current_state));
  626. } else {
  627. */ return btfmcodec_hwep_get_channel_map((void *)btfmcodec->hwep_info,
  628. tx_num, tx_slot, rx_num,
  629. rx_slot, dai->id);
  630. // }
  631. return 0;
  632. }
  633. void btfmcodec_wq_hwep_configure(struct work_struct *work)
  634. {
  635. struct btfmcodec_char_device *btfmcodec_dev = container_of(work,
  636. struct btfmcodec_char_device,
  637. wq_hwep_configure);
  638. struct btfmcodec_data *btfmcodec = (struct btfmcodec_data *)btfmcodec_dev->btfmcodec;
  639. struct list_head *head = &btfmcodec->config_head;
  640. struct hwep_configurations *hwep_configs = NULL, *tmp;
  641. int ret;
  642. int idx = BTM_PKT_TYPE_HWEP_CONFIG;
  643. uint32_t sample_rate, direction;
  644. uint8_t id, bit_width, codectype, num_channels;
  645. list_for_each_entry_safe(hwep_configs, tmp, head, dai_list) {
  646. id = hwep_configs->stream_id;
  647. sample_rate = hwep_configs->sample_rate;
  648. bit_width = hwep_configs->bit_width;
  649. codectype = hwep_configs->codectype;
  650. direction = hwep_configs->direction;
  651. num_channels = hwep_configs->num_channels;
  652. BTFMCODEC_INFO("configuring dai id:%d with sampling rate:%d bit_width:%d", id, sample_rate, bit_width);
  653. ret = btfmcodec_hwep_startup(btfmcodec);
  654. if (ret >= 0)
  655. ret = btfmcodec_hwep_hw_params(btfmcodec, bit_width, direction, num_channels);
  656. if (ret >= 0)
  657. ret = btfmcodec_hwep_prepare(btfmcodec, sample_rate, direction, id);
  658. if (ret < 0) {
  659. BTFMCODEC_ERR("failed to configure hwep %d", hwep_configs->stream_id);
  660. break;
  661. }
  662. }
  663. if (ret < 0)
  664. btfmcodec_dev->status[idx] = BTM_FAIL_RESP_RECV;
  665. else
  666. btfmcodec_dev->status[idx] = BTM_RSP_RECV;
  667. wake_up_interruptible(&btfmcodec_dev->rsp_wait_q[idx]);
  668. }
  669. static struct snd_soc_dai_ops btfmcodec_dai_ops = {
  670. .startup = btfmcodec_dai_startup,
  671. .shutdown = btfmcodec_dai_shutdown,
  672. .hw_params = btfmcodec_dai_hw_params,
  673. .prepare = btfmcodec_dai_prepare,
  674. .set_channel_map = btfmcodec_dai_set_channel_map,
  675. .get_channel_map = btfmcodec_dai_get_channel_map,
  676. };
  677. static int btfmcodec_adsp_ssr_notify(struct notifier_block *nb,
  678. unsigned long action, void *data)
  679. {
  680. struct btfmcodec_data *btfmcodec = container_of(nb,
  681. struct btfmcodec_data, notifier.nb);
  682. struct btfmcodec_char_device *btfmcodec_dev = btfmcodec->btfmcodec_dev;
  683. struct btm_adsp_state_ind state_ind;
  684. switch (action) {
  685. case QCOM_SSR_BEFORE_SHUTDOWN: {
  686. BTFMCODEC_WARN("LPASS SSR triggered");
  687. break;
  688. } case QCOM_SSR_AFTER_SHUTDOWN: {
  689. BTFMCODEC_WARN("LPASS SSR Completed");
  690. break;
  691. } case QCOM_SSR_BEFORE_POWERUP: {
  692. BTFMCODEC_WARN("LPASS booted up after SSR");
  693. break;
  694. } case QCOM_SSR_AFTER_POWERUP: {
  695. BTFMCODEC_WARN("LPASS booted up completely");
  696. state_ind.opcode = BTM_BTFMCODEC_ADSP_STATE_IND;
  697. state_ind.len = BTM_ADSP_STATE_IND_LEN;
  698. state_ind.action = (uint32_t)action;
  699. btfmcodec_dev_enqueue_pkt(btfmcodec_dev, &state_ind,
  700. (state_ind.len +
  701. BTM_HEADER_LEN));
  702. break;
  703. } default:
  704. BTFMCODEC_WARN("unhandled action id %lu", action);
  705. break;
  706. }
  707. return 0;
  708. }
  709. int btfm_register_codec(struct hwep_data *hwep_info)
  710. {
  711. struct btfmcodec_data *btfmcodec;
  712. struct btfmcodec_char_device *btfmcodec_dev;
  713. struct device *dev;
  714. struct hwep_dai_driver *dai_drv;
  715. int i, ret;
  716. btfmcodec = btfm_get_btfmcodec();
  717. btfmcodec_dev = btfmcodec->btfmcodec_dev;
  718. dev = &btfmcodec->dev;
  719. btfmcodec->notifier.nb.notifier_call = btfmcodec_adsp_ssr_notify;
  720. btfmcodec->notifier.notifier = qcom_register_ssr_notifier("lpass",
  721. &btfmcodec->notifier.nb);
  722. if (IS_ERR(btfmcodec->notifier.notifier)) {
  723. ret = PTR_ERR(btfmcodec->notifier.notifier);
  724. BTFMCODEC_ERR("Failed to register SSR notification: %d\n", ret);
  725. return ret;
  726. }
  727. btfmcodec_dai_info = kzalloc((sizeof(struct snd_soc_dai_driver) * hwep_info->num_dai), GFP_KERNEL);
  728. if (!btfmcodec_dai_info) {
  729. BTFMCODEC_ERR("failed to allocate memory");
  730. return -ENOMEM;
  731. }
  732. for (i = 0; i < hwep_info->num_dai; i++) {
  733. dai_drv = &hwep_info->dai_drv[i];
  734. btfmcodec_dai_info[i].name = dai_drv->dai_name;
  735. btfmcodec_dai_info[i].id = dai_drv->id;
  736. btfmcodec_dai_info[i].capture = dai_drv->capture;
  737. btfmcodec_dai_info[i].playback = dai_drv->playback;
  738. btfmcodec_dai_info[i].ops = &btfmcodec_dai_ops;
  739. }
  740. BTFMCODEC_INFO("Adding %d dai support to codec", hwep_info->num_dai);
  741. BTFMCODEC_INFO("slim bus driver name:%s", dev->driver->name);
  742. ret = snd_soc_register_component(dev, &btfmcodec_codec_component,
  743. btfmcodec_dai_info, hwep_info->num_dai);
  744. BTFMCODEC_INFO("Dev node address: %p", dev);
  745. BTFMCODEC_INFO("btfmcodec address :%p", btfmcodec);
  746. BTFMCODEC_INFO("HWEPINFO address:%p", hwep_info);
  747. BTFMCODEC_INFO("btfmcodec_dev INFO address:%p", btfmcodec->btfmcodec_dev);
  748. BTFMCODEC_INFO("before wq_hwep_shutdown:%p", btfmcodec_dev->wq_hwep_shutdown);
  749. BTFMCODEC_INFO("before wq_prepare_bearer:%p", btfmcodec_dev->wq_prepare_bearer);
  750. INIT_WORK(&btfmcodec_dev->wq_hwep_shutdown, btfmcodec_wq_hwep_shutdown);
  751. INIT_WORK(&btfmcodec_dev->wq_prepare_bearer, btfmcodec_wq_prepare_bearer);
  752. INIT_WORK(&btfmcodec_dev->wq_hwep_configure, btfmcodec_wq_hwep_configure);
  753. BTFMCODEC_INFO("after wq_hwep_shutdown:%p", btfmcodec_dev->wq_hwep_shutdown);
  754. BTFMCODEC_INFO("after wq_prepare_bearer:%p", btfmcodec_dev->wq_prepare_bearer);
  755. BTFMCODEC_INFO("btfmcodec_wq_prepare_bearer:%p", btfmcodec_wq_prepare_bearer);
  756. BTFMCODEC_INFO("btfmcodec_wq_hwep_shutdown:%p", btfmcodec_wq_hwep_shutdown);
  757. if (isCpSupported()) {
  758. if (!strcmp(hwep_info->driver_name, "btfmslim"))
  759. set_bit(BTADV_AUDIO_MASTER_CONFIG, &hwep_info->flags);
  760. else if (!strcmp(hwep_info->driver_name, "btfmswr_slave"))
  761. set_bit(BTADV_CONFIGURE_DMA, &hwep_info->flags);
  762. BTFMCODEC_INFO("%s: master %d dma codec %d", __func__,
  763. (int)test_bit(BTADV_AUDIO_MASTER_CONFIG, &hwep_info->flags),
  764. (int)test_bit(BTADV_CONFIGURE_DMA, &hwep_info->flags));
  765. }
  766. return ret;
  767. }
  768. void btfm_unregister_codec(void)
  769. {
  770. struct btfmcodec_data *btfmcodec;
  771. btfmcodec = btfm_get_btfmcodec();
  772. snd_soc_unregister_component(&btfmcodec->dev);
  773. }