btfm_slim.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/init.h>
  7. #include <linux/kernel.h>
  8. #include <linux/module.h>
  9. #include <linux/of_gpio.h>
  10. #include <linux/delay.h>
  11. #include <linux/gpio.h>
  12. #include <linux/debugfs.h>
  13. #include <linux/ratelimit.h>
  14. #include <linux/slab.h>
  15. #include <linux/fs.h>
  16. #include <sound/pcm.h>
  17. #include <sound/pcm_params.h>
  18. #include <sound/soc.h>
  19. #include <sound/soc-dapm.h>
  20. #include <sound/tlv.h>
  21. #include "btpower.h"
  22. #include "btfm_slim.h"
  23. #include "btfm_slim_slave.h"
  24. #if IS_ENABLED(CONFIG_SLIM_BTFM_CODEC)
  25. #include "btfm_slim_hw_interface.h"
  26. #endif
  27. #define DELAY_FOR_PORT_OPEN_MS (200)
  28. #define SLIM_MANF_ID_QCOM 0x217
  29. #define SLIM_PROD_CODE 0x221
  30. #define BT_CMD_SLIM_TEST 0xbfac
  31. struct class *btfm_slim_class;
  32. static int btfm_slim_major;
  33. struct btfmslim *btfm_slim_drv_data;
  34. static int btfm_num_ports_open;
  35. int btfm_slim_write(struct btfmslim *btfmslim,
  36. uint16_t reg, uint8_t reg_val, uint8_t pgd)
  37. {
  38. int ret = -1;
  39. uint32_t reg_addr;
  40. int slim_write_tries = SLIM_SLAVE_RW_MAX_TRIES;
  41. BTFMSLIM_INFO("Write to %s", pgd?"PGD":"IFD");
  42. reg_addr = SLIM_SLAVE_REG_OFFSET + reg;
  43. for ( ; slim_write_tries != 0; slim_write_tries--) {
  44. mutex_lock(&btfmslim->xfer_lock);
  45. ret = slim_writeb(pgd ? btfmslim->slim_pgd :
  46. &btfmslim->slim_ifd, reg_addr, reg_val);
  47. mutex_unlock(&btfmslim->xfer_lock);
  48. if (ret) {
  49. BTFMSLIM_DBG("retrying to Write 0x%02x to reg 0x%x ret %d",
  50. reg_val, reg_addr, ret);
  51. } else {
  52. BTFMSLIM_DBG("Written 0x%02x to reg 0x%x ret %d", reg_val, reg_addr, ret);
  53. break;
  54. }
  55. usleep_range(5000, 5100);
  56. }
  57. if (ret) {
  58. BTFMSLIM_DBG("retrying to Write 0x%02x to reg 0x%x ret %d",
  59. reg_val, reg_addr, ret);
  60. }
  61. return ret;
  62. }
  63. int btfm_slim_read(struct btfmslim *btfmslim, uint32_t reg, uint8_t pgd)
  64. {
  65. int ret = -1;
  66. int slim_read_tries = SLIM_SLAVE_RW_MAX_TRIES;
  67. uint32_t reg_addr;
  68. BTFMSLIM_DBG("Read from %s", pgd?"PGD":"IFD");
  69. reg_addr = SLIM_SLAVE_REG_OFFSET + reg;
  70. for ( ; slim_read_tries != 0; slim_read_tries--) {
  71. mutex_lock(&btfmslim->xfer_lock);
  72. ret = slim_readb(pgd ? btfmslim->slim_pgd :
  73. &btfmslim->slim_ifd, reg_addr);
  74. BTFMSLIM_DBG("Read 0x%02x from reg 0x%x", ret, reg_addr);
  75. mutex_unlock(&btfmslim->xfer_lock);
  76. if (ret > 0)
  77. break;
  78. usleep_range(5000, 5100);
  79. }
  80. return ret;
  81. }
  82. int btfm_slim_enable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
  83. uint8_t rxport, uint32_t rates, uint8_t nchan)
  84. {
  85. int ret = -1;
  86. int i = 0;
  87. struct btfmslim_ch *chan = ch;
  88. int chipset_ver;
  89. if (!btfmslim || !ch)
  90. return -EINVAL;
  91. BTFMSLIM_DBG("port: %d ch: %d", ch->port, ch->ch);
  92. chan->dai.sruntime = slim_stream_allocate(btfmslim->slim_pgd, "BTFM_SLIM");
  93. if (chan->dai.sruntime == NULL) {
  94. BTFMSLIM_ERR("slim_stream_allocate failed");
  95. return -EINVAL;
  96. }
  97. chan->dai.sconfig.bps = btfmslim->bps;
  98. chan->dai.sconfig.direction = btfmslim->direction;
  99. chan->dai.sconfig.rate = rates;
  100. chan->dai.sconfig.ch_count = nchan;
  101. chan->dai.sconfig.chs = kcalloc(nchan, sizeof(unsigned int), GFP_KERNEL);
  102. if (!chan->dai.sconfig.chs)
  103. return -ENOMEM;
  104. for (i = 0; i < nchan; i++, ch++) {
  105. /* Enable port through registration setting */
  106. if (btfmslim->vendor_port_en) {
  107. ret = btfmslim->vendor_port_en(btfmslim, ch->port,
  108. rxport, 1);
  109. if (ret < 0) {
  110. BTFMSLIM_ERR("vendor_port_en failed ret[%d]",
  111. ret);
  112. goto error;
  113. }
  114. }
  115. chan->dai.sconfig.chs[i] = ch->ch;
  116. chan->dai.sconfig.port_mask |= BIT(ch->port);
  117. }
  118. /* Activate the channel immediately */
  119. BTFMSLIM_INFO("port: %d, ch: %d", chan->port, chan->ch);
  120. chipset_ver = btpower_get_chipset_version();
  121. BTFMSLIM_INFO("chipset soc version:%x", chipset_ver);
  122. /* for feedback channel, PCM bit should not be set */
  123. if (btfm_feedback_ch_setting) {
  124. BTFMSLIM_DBG("port open for feedback ch, not setting PCM bit");
  125. //prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
  126. /* reset so that next port open sets the data format properly */
  127. btfm_feedback_ch_setting = 0;
  128. }
  129. ret = slim_stream_prepare(chan->dai.sruntime, &chan->dai.sconfig);
  130. if (ret) {
  131. BTFMSLIM_ERR("slim_stream_prepare failed = %d", ret);
  132. goto error;
  133. }
  134. ret = slim_stream_enable(chan->dai.sruntime);
  135. if (ret) {
  136. BTFMSLIM_ERR("slim_stream_enable failed = %d", ret);
  137. goto error;
  138. }
  139. if (ret == 0)
  140. btfm_num_ports_open++;
  141. BTFMSLIM_INFO("btfm_num_ports_open: %d", btfm_num_ports_open);
  142. return ret;
  143. error:
  144. BTFMSLIM_INFO("error %d while opening port, btfm_num_ports_open: %d",
  145. ret, btfm_num_ports_open);
  146. kfree(chan->dai.sconfig.chs);
  147. chan->dai.sconfig.chs = NULL;
  148. return ret;
  149. }
  150. int btfm_slim_disable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
  151. uint8_t rxport, uint8_t nchan)
  152. {
  153. int ret = -1;
  154. int i = 0;
  155. int chipset_ver = 0;
  156. if (!btfmslim || !ch)
  157. return -EINVAL;
  158. BTFMSLIM_INFO("port:%d ", ch->port);
  159. if (ch->dai.sruntime == NULL) {
  160. BTFMSLIM_ERR("Channel not enabled yet. returning");
  161. return -EINVAL;
  162. }
  163. if (rxport && (btfmslim->sample_rate == 44100 ||
  164. btfmslim->sample_rate == 88200)) {
  165. BTFMSLIM_INFO("disconnecting the ports, removing the channel");
  166. /* disconnect the ports of the stream */
  167. ret = slim_stream_unprepare_disconnect_port(ch->dai.sruntime,
  168. true, false);
  169. if (ret != 0)
  170. BTFMSLIM_ERR("slim_stream_unprepare failed %d", ret);
  171. }
  172. ret = slim_stream_disable(ch->dai.sruntime);
  173. if (ret != 0) {
  174. BTFMSLIM_ERR("slim_stream_disable failed returned val = %d", ret);
  175. if ((btfmslim->sample_rate != 44100) && (btfmslim->sample_rate != 88200)) {
  176. /* disconnect the ports of the stream */
  177. ret = slim_stream_unprepare_disconnect_port(ch->dai.sruntime,
  178. true, false);
  179. if (ret != 0)
  180. BTFMSLIM_ERR("slim_stream_unprepare failed %d", ret);
  181. }
  182. }
  183. /* free the ports allocated to the stream */
  184. ret = slim_stream_unprepare_disconnect_port(ch->dai.sruntime, false, true);
  185. if (ret != 0)
  186. BTFMSLIM_ERR("slim_stream_unprepare failed returned val = %d", ret);
  187. /* Disable port through registration setting */
  188. for (i = 0; i < nchan; i++, ch++) {
  189. if (btfmslim->vendor_port_en) {
  190. ret = btfmslim->vendor_port_en(btfmslim, ch->port,
  191. rxport, 0);
  192. if (ret < 0) {
  193. BTFMSLIM_ERR("vendor_port_en failed [%d]", ret);
  194. break;
  195. }
  196. }
  197. }
  198. ch->dai.sconfig.port_mask = 0;
  199. if (ch->dai.sconfig.chs != NULL)
  200. kfree(ch->dai.sconfig.chs);
  201. if (btfm_num_ports_open > 0)
  202. btfm_num_ports_open--;
  203. ch->dai.sruntime = NULL;
  204. BTFMSLIM_INFO("btfm_num_ports_open: %d", btfm_num_ports_open);
  205. chipset_ver = btpower_get_chipset_version();
  206. if (btfm_num_ports_open == 0 && (chipset_ver == QCA_HSP_SOC_ID_0200 ||
  207. chipset_ver == QCA_HSP_SOC_ID_0210 ||
  208. chipset_ver == QCA_HSP_SOC_ID_1201 ||
  209. chipset_ver == QCA_HSP_SOC_ID_1211 ||
  210. chipset_ver == QCA_HAMILTON_SOC_ID_0100 ||
  211. chipset_ver == QCA_HAMILTON_SOC_ID_0101 ||
  212. chipset_ver == QCA_HAMILTON_SOC_ID_0200 )) {
  213. BTFMSLIM_INFO("SB reset needed after all ports disabled, sleeping");
  214. msleep(DELAY_FOR_PORT_OPEN_MS);
  215. }
  216. return ret;
  217. }
  218. static int btfm_slim_alloc_port(struct btfmslim *btfmslim)
  219. {
  220. int ret = -EINVAL, i;
  221. int chipset_ver;
  222. struct btfmslim_ch *rx_chs;
  223. struct btfmslim_ch *tx_chs;
  224. if (!btfmslim)
  225. return ret;
  226. chipset_ver = btpower_get_chipset_version();
  227. BTFMSLIM_INFO("chipset soc version:%x", chipset_ver);
  228. rx_chs = btfmslim->rx_chs;
  229. tx_chs = btfmslim->tx_chs;
  230. if ((chipset_ver >= QCA_CHEROKEE_SOC_ID_0310) &&
  231. (chipset_ver <= QCA_CHEROKEE_SOC_ID_0320_UMC)) {
  232. for (i = 0; (tx_chs->port != BTFM_SLIM_PGD_PORT_LAST) &&
  233. (i < BTFM_SLIM_NUM_CODEC_DAIS); i++, tx_chs++) {
  234. if (tx_chs->port == SLAVE_SB_PGD_PORT_TX1_FM)
  235. tx_chs->port = CHRKVER3_SB_PGD_PORT_TX1_FM;
  236. else if (tx_chs->port == SLAVE_SB_PGD_PORT_TX2_FM)
  237. tx_chs->port = CHRKVER3_SB_PGD_PORT_TX2_FM;
  238. BTFMSLIM_INFO("Tx port:%d", tx_chs->port);
  239. }
  240. tx_chs = btfmslim->tx_chs;
  241. }
  242. if (!rx_chs || !tx_chs)
  243. return ret;
  244. return 0;
  245. }
  246. static int btfm_slim_get_logical_addr(struct slim_device *slim)
  247. {
  248. int ret = 0;
  249. const unsigned long timeout = jiffies +
  250. msecs_to_jiffies(SLIM_SLAVE_PRESENT_TIMEOUT);
  251. BTFMSLIM_INFO("");
  252. do {
  253. ret = slim_get_logical_addr(slim);
  254. if (!ret) {
  255. BTFMSLIM_DBG("Assigned l-addr: 0x%x", slim->laddr);
  256. break;
  257. }
  258. /* Give SLIMBUS time to report present and be ready. */
  259. usleep_range(1000, 1100);
  260. BTFMSLIM_DBG("retyring get logical addr");
  261. } while (time_before(jiffies, timeout));
  262. return ret;
  263. }
  264. int btfm_slim_hw_init(struct btfmslim *btfmslim)
  265. {
  266. int ret = -1;
  267. int chipset_ver;
  268. struct slim_device *slim;
  269. struct slim_device *slim_ifd;
  270. BTFMSLIM_DBG("");
  271. if (!btfmslim)
  272. return -EINVAL;
  273. if (btfmslim->enabled) {
  274. BTFMSLIM_DBG("Already enabled");
  275. return 0;
  276. }
  277. slim = btfmslim->slim_pgd;
  278. slim_ifd = &btfmslim->slim_ifd;
  279. mutex_lock(&btfmslim->io_lock);
  280. BTFMSLIM_INFO(
  281. "PGD Enum Addr: mfr id:%.02x prod code:%.02x dev ind:%.02x ins:%.02x",
  282. slim->e_addr.manf_id, slim->e_addr.prod_code,
  283. slim->e_addr.dev_index, slim->e_addr.instance);
  284. chipset_ver = btpower_get_chipset_version();
  285. BTFMSLIM_INFO("chipset soc version:%x", chipset_ver);
  286. if (chipset_ver == QCA_HSP_SOC_ID_0100 ||
  287. chipset_ver == QCA_HSP_SOC_ID_0110 ||
  288. chipset_ver == QCA_HSP_SOC_ID_0200 ||
  289. chipset_ver == QCA_HSP_SOC_ID_0210 ||
  290. chipset_ver == QCA_HSP_SOC_ID_1201 ||
  291. chipset_ver == QCA_HSP_SOC_ID_1211) {
  292. BTFMSLIM_INFO("chipset is hastings prime, overwriting EA");
  293. slim->is_laddr_valid = false;
  294. slim->e_addr.manf_id = SLIM_MANF_ID_QCOM;
  295. slim->e_addr.prod_code = SLIM_PROD_CODE;
  296. slim->e_addr.dev_index = 0x01;
  297. slim->e_addr.instance = 0x0;
  298. /* we are doing this to indicate that this is not a child node
  299. * (doesn't have call back functions). Needed only for querying
  300. * logical address.
  301. */
  302. slim_ifd->dev.driver = NULL;
  303. slim_ifd->ctrl = btfmslim->slim_pgd->ctrl; //slimbus controller structure.
  304. slim_ifd->is_laddr_valid = false;
  305. slim_ifd->e_addr.manf_id = SLIM_MANF_ID_QCOM;
  306. slim_ifd->e_addr.prod_code = SLIM_PROD_CODE;
  307. slim_ifd->e_addr.dev_index = 0x0;
  308. slim_ifd->e_addr.instance = 0x0;
  309. slim_ifd->laddr = 0x0;
  310. } else if (chipset_ver == QCA_MOSELLE_SOC_ID_0100 ||
  311. chipset_ver == QCA_MOSELLE_SOC_ID_0110) {
  312. BTFMSLIM_INFO("chipset is Moselle, overwriting EA");
  313. slim->is_laddr_valid = false;
  314. slim->e_addr.manf_id = SLIM_MANF_ID_QCOM;
  315. slim->e_addr.prod_code = 0x222;
  316. slim->e_addr.dev_index = 0x01;
  317. slim->e_addr.instance = 0x0;
  318. /* we are doing this to indicate that this is not a child node
  319. * (doesn't have call back functions). Needed only for querying
  320. * logical address.
  321. */
  322. slim_ifd->dev.driver = NULL;
  323. slim_ifd->ctrl = btfmslim->slim_pgd->ctrl; //slimbus controller structure.
  324. slim_ifd->is_laddr_valid = false;
  325. slim_ifd->e_addr.manf_id = SLIM_MANF_ID_QCOM;
  326. slim_ifd->e_addr.prod_code = 0x222;
  327. slim_ifd->e_addr.dev_index = 0x0;
  328. slim_ifd->e_addr.instance = 0x0;
  329. slim_ifd->laddr = 0x0;
  330. } else if (chipset_ver == QCA_HAMILTON_SOC_ID_0100 ||
  331. chipset_ver == QCA_HAMILTON_SOC_ID_0101 ||
  332. chipset_ver == QCA_HAMILTON_SOC_ID_0200) {
  333. BTFMSLIM_INFO("chipset is Hamliton, overwriting EA");
  334. slim->is_laddr_valid = false;
  335. slim->e_addr.manf_id = SLIM_MANF_ID_QCOM;
  336. slim->e_addr.prod_code = 0x220;
  337. slim->e_addr.dev_index = 0x01;
  338. slim->e_addr.instance = 0x0;
  339. /* we are doing this to indicate that this is not a child node
  340. * (doesn't have call back functions). Needed only for querying
  341. * logical address.
  342. */
  343. slim_ifd->dev.driver = NULL;
  344. slim_ifd->ctrl = btfmslim->slim_pgd->ctrl; //slimbus controller structure.
  345. slim_ifd->is_laddr_valid = false;
  346. slim_ifd->e_addr.manf_id = SLIM_MANF_ID_QCOM;
  347. slim_ifd->e_addr.prod_code = 0x220;
  348. slim_ifd->e_addr.dev_index = 0x0;
  349. slim_ifd->e_addr.instance = 0x0;
  350. slim_ifd->laddr = 0x0;
  351. } else if (chipset_ver == QCA_CHEROKEE_SOC_ID_0200 ||
  352. chipset_ver == QCA_CHEROKEE_SOC_ID_0201 ||
  353. chipset_ver == QCA_CHEROKEE_SOC_ID_0210 ||
  354. chipset_ver == QCA_CHEROKEE_SOC_ID_0211 ||
  355. chipset_ver == QCA_CHEROKEE_SOC_ID_0310 ||
  356. chipset_ver == QCA_CHEROKEE_SOC_ID_0320 ||
  357. chipset_ver == QCA_CHEROKEE_SOC_ID_0320_UMC ||
  358. chipset_ver == QCA_APACHE_SOC_ID_0100 ||
  359. chipset_ver == QCA_APACHE_SOC_ID_0110 ||
  360. chipset_ver == QCA_APACHE_SOC_ID_0120 ||
  361. chipset_ver == QCA_APACHE_SOC_ID_0121) {
  362. BTFMSLIM_INFO("chipset is Chk/Apache, overwriting EA");
  363. slim->is_laddr_valid = false;
  364. slim->e_addr.manf_id = SLIM_MANF_ID_QCOM;
  365. slim->e_addr.prod_code = 0x220;
  366. slim->e_addr.dev_index = 0x01;
  367. slim->e_addr.instance = 0x0;
  368. /* we are doing this to indicate that this is not a child node
  369. * (doesn't have call back functions). Needed only for querying
  370. * logical address.
  371. */
  372. slim_ifd->dev.driver = NULL;
  373. slim_ifd->ctrl = btfmslim->slim_pgd->ctrl; //slimbus controller structure.
  374. slim_ifd->is_laddr_valid = false;
  375. slim_ifd->e_addr.manf_id = SLIM_MANF_ID_QCOM;
  376. slim_ifd->e_addr.prod_code = 0x220;
  377. slim_ifd->e_addr.dev_index = 0x0;
  378. slim_ifd->e_addr.instance = 0x0;
  379. slim_ifd->laddr = 0x0;
  380. }
  381. BTFMSLIM_INFO(
  382. "PGD Enum Addr: manu id:%.02x prod code:%.02x dev idx:%.02x instance:%.02x",
  383. slim->e_addr.manf_id, slim->e_addr.prod_code,
  384. slim->e_addr.dev_index, slim->e_addr.instance);
  385. BTFMSLIM_INFO(
  386. "IFD Enum Addr: manu id:%.02x prod code:%.02x dev idx:%.02x instance:%.02x",
  387. slim_ifd->e_addr.manf_id, slim_ifd->e_addr.prod_code,
  388. slim_ifd->e_addr.dev_index, slim_ifd->e_addr.instance);
  389. /* Assign Logical Address for PGD (Ported Generic Device)
  390. * enumeration address
  391. */
  392. ret = btfm_slim_get_logical_addr(btfmslim->slim_pgd);
  393. if (ret) {
  394. BTFMSLIM_ERR("failed to get slimbus logical address: %d", ret);
  395. goto error;
  396. }
  397. /* Assign Logical Address for Ported Generic Device
  398. * enumeration address
  399. */
  400. ret = btfm_slim_get_logical_addr(&btfmslim->slim_ifd);
  401. if (ret) {
  402. BTFMSLIM_ERR("failed to get slimbus logical address: %d", ret);
  403. goto error;
  404. }
  405. ret = btfm_slim_alloc_port(btfmslim);
  406. if (ret != 0)
  407. goto error;
  408. /* Start vendor specific initialization and get port information */
  409. if (btfmslim->vendor_init)
  410. ret = btfmslim->vendor_init(btfmslim);
  411. /* Only when all registers read/write successfully, it set to
  412. * enabled status
  413. */
  414. btfmslim->enabled = 1;
  415. error:
  416. mutex_unlock(&btfmslim->io_lock);
  417. return ret;
  418. }
  419. int btfm_slim_hw_deinit(struct btfmslim *btfmslim)
  420. {
  421. int ret = 0;
  422. BTFMSLIM_INFO("");
  423. if (!btfmslim)
  424. return -EINVAL;
  425. if (!btfmslim->enabled) {
  426. BTFMSLIM_DBG("Already disabled");
  427. return 0;
  428. }
  429. mutex_lock(&btfmslim->io_lock);
  430. btfmslim->enabled = 0;
  431. mutex_unlock(&btfmslim->io_lock);
  432. return ret;
  433. }
  434. #if IS_ENABLED (CONFIG_BTFM_SLIM)
  435. void btfm_slim_get_hwep_details(struct slim_device *dev, struct btfmslim *btfm_slim)
  436. {
  437. }
  438. #else
  439. void btfm_slim_get_hwep_details(struct slim_device *slim, struct btfmslim *btfm_slim)
  440. {
  441. struct device_node *np = slim->dev.of_node;
  442. const __be32 *prop;
  443. struct btfmslim_ch *rx_chs = btfm_slim->rx_chs;
  444. struct btfmslim_ch *tx_chs = btfm_slim->tx_chs;
  445. int len;
  446. prop = of_get_property(np, "qcom,btslim-address", &len);
  447. if (prop) {
  448. btfm_slim->device_id = be32_to_cpup(&prop[0]);
  449. BTFMSLIM_DBG("hwep slim address define in dt %08x", btfm_slim->device_id);
  450. } else {
  451. BTFMSLIM_ERR("btslim-address is not defined in dt using default address");
  452. btfm_slim->device_id = 0;
  453. }
  454. if (!rx_chs || !tx_chs) {
  455. BTFMSLIM_ERR("either rx/tx channels are configured to null");
  456. return;
  457. }
  458. prop = of_get_property(np, "qcom,btslimrx-channels", &len);
  459. if (prop) {
  460. /* Check if we need any protection for index */
  461. rx_chs[0].ch = (uint8_t)be32_to_cpup(&prop[0]);
  462. rx_chs[1].ch = (uint8_t)be32_to_cpup(&prop[1]);
  463. BTFMSLIM_DBG("Rx: id\tname\tport\tch");
  464. BTFMSLIM_DBG(" %d\t%s\t%d\t%d", rx_chs[0].id,
  465. rx_chs[0].name, rx_chs[0].port,
  466. rx_chs[0].ch);
  467. BTFMSLIM_DBG(" %d\t%s\t%d\t%d", rx_chs[1].id,
  468. rx_chs[1].name, rx_chs[1].port,
  469. rx_chs[1].ch);
  470. } else {
  471. BTFMSLIM_ERR("btslimrx channels are missing in dt using default values");
  472. }
  473. prop = of_get_property(np, "qcom,btslimtx-channels", &len);
  474. if (prop) {
  475. /* Check if we need any protection for index */
  476. tx_chs[0].ch = (uint8_t)be32_to_cpup(&prop[0]);
  477. tx_chs[1].ch = (uint8_t)be32_to_cpup(&prop[1]);
  478. BTFMSLIM_DBG("Tx: id\tname\tport\tch");
  479. BTFMSLIM_DBG(" %d\t%s\t%d\t%x", tx_chs[0].id,
  480. tx_chs[0].name, tx_chs[0].port,
  481. tx_chs[0].ch);
  482. BTFMSLIM_DBG(" %d\t%s\t%d\t%x", tx_chs[1].id,
  483. tx_chs[1].name, tx_chs[1].port,
  484. tx_chs[1].ch);
  485. } else {
  486. BTFMSLIM_ERR("btslimtx channels are missing in dt using default values");
  487. }
  488. }
  489. #endif
  490. static int btfm_slim_status(struct slim_device *sdev,
  491. enum slim_device_status status)
  492. {
  493. int ret = 0;
  494. struct device *dev = &sdev->dev;
  495. struct btfmslim *btfm_slim;
  496. btfm_slim = dev_get_drvdata(dev);
  497. #if IS_ENABLED(CONFIG_BTFM_SLIM)
  498. ret = btfm_slim_register_codec(btfm_slim);
  499. #else
  500. btfm_slim_get_hwep_details(sdev, btfm_slim);
  501. ret = btfm_slim_register_hw_ep(btfm_slim);
  502. #endif
  503. if (ret)
  504. BTFMSLIM_ERR("error, registering slimbus codec failed");
  505. return ret;
  506. }
  507. static long btfm_slim_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  508. {
  509. int ret = 0;
  510. switch (cmd) {
  511. case BT_CMD_SLIM_TEST:
  512. BTFMSLIM_INFO("cmd BT_CMD_SLIM_TEST, call btfm_slim_hw_init");
  513. ret = btfm_slim_hw_init(btfm_slim_drv_data);
  514. break;
  515. }
  516. return ret;
  517. }
  518. static const struct file_operations bt_dev_fops = {
  519. .unlocked_ioctl = btfm_slim_ioctl,
  520. .compat_ioctl = btfm_slim_ioctl,
  521. };
  522. static int btfm_slim_probe(struct slim_device *slim)
  523. {
  524. int ret = 0;
  525. struct btfmslim *btfm_slim;
  526. pr_info("%s: name = %s\n", __func__, dev_name(&slim->dev));
  527. /*this as true during the probe then slimbus won't check for logical address*/
  528. slim->is_laddr_valid = true;
  529. dev_set_name(&slim->dev, "%s", BTFMSLIM_DEV_NAME);
  530. pr_info("%s: name = %s\n", __func__, dev_name(&slim->dev));
  531. BTFMSLIM_DBG("");
  532. BTFMSLIM_ERR("is_laddr_valid is true");
  533. if (!slim->ctrl)
  534. return -EINVAL;
  535. /* Allocation btfmslim data pointer */
  536. btfm_slim = kzalloc(sizeof(struct btfmslim), GFP_KERNEL);
  537. if (btfm_slim == NULL) {
  538. BTFMSLIM_ERR("error, allocation failed");
  539. return -ENOMEM;
  540. }
  541. /* BTFM Slimbus driver control data configuration */
  542. btfm_slim->slim_pgd = slim;
  543. /* Assign vendor specific function */
  544. btfm_slim->rx_chs = SLIM_SLAVE_RXPORT;
  545. btfm_slim->tx_chs = SLIM_SLAVE_TXPORT;
  546. btfm_slim->vendor_init = SLIM_SLAVE_INIT;
  547. btfm_slim->vendor_port_en = SLIM_SLAVE_PORT_EN;
  548. /* Created Mutex for slimbus data transfer */
  549. mutex_init(&btfm_slim->io_lock);
  550. mutex_init(&btfm_slim->xfer_lock);
  551. dev_set_drvdata(&slim->dev, btfm_slim);
  552. /* Driver specific data allocation */
  553. btfm_slim->dev = &slim->dev;
  554. ret = btpower_register_slimdev(&slim->dev);
  555. if (ret < 0) {
  556. #if IS_ENABLED(CONFIG_BTFM_SLIM)
  557. btfm_slim_unregister_codec(&slim->dev);
  558. #else
  559. btfm_slim_unregister_hwep();
  560. #endif
  561. ret = -EPROBE_DEFER;
  562. goto dealloc;
  563. }
  564. btfm_slim_drv_data = btfm_slim;
  565. btfm_slim_major = register_chrdev(0, "btfm_slim", &bt_dev_fops);
  566. if (btfm_slim_major < 0) {
  567. BTFMSLIM_ERR("%s: failed to allocate char dev\n", __func__);
  568. ret = -1;
  569. goto register_err;
  570. }
  571. btfm_slim_class = class_create(THIS_MODULE, "btfmslim-dev");
  572. if (IS_ERR(btfm_slim_class)) {
  573. BTFMSLIM_ERR("%s: coudn't create class\n", __func__);
  574. ret = -1;
  575. goto class_err;
  576. }
  577. if (device_create(btfm_slim_class, NULL, MKDEV(btfm_slim_major, 0),
  578. NULL, "btfmslim") == NULL) {
  579. BTFMSLIM_ERR("%s: failed to allocate char dev\n", __func__);
  580. ret = -1;
  581. goto device_err;
  582. }
  583. return ret;
  584. device_err:
  585. class_destroy(btfm_slim_class);
  586. class_err:
  587. unregister_chrdev(btfm_slim_major, "btfm_slim");
  588. register_err:
  589. btfm_slim_unregister_codec(&slim->dev);
  590. dealloc:
  591. mutex_destroy(&btfm_slim->io_lock);
  592. mutex_destroy(&btfm_slim->xfer_lock);
  593. kfree(btfm_slim);
  594. return ret;
  595. }
  596. static void btfm_slim_remove(struct slim_device *slim)
  597. {
  598. struct device *dev = &slim->dev;
  599. struct btfmslim *btfm_slim = dev_get_drvdata(dev);
  600. BTFMSLIM_DBG("");
  601. mutex_destroy(&btfm_slim->io_lock);
  602. mutex_destroy(&btfm_slim->xfer_lock);
  603. snd_soc_unregister_component(&slim->dev);
  604. kfree(btfm_slim);
  605. }
  606. static const struct slim_device_id btfm_slim_id[] = {
  607. {
  608. .manf_id = SLIM_MANF_ID_QCOM,
  609. .prod_code = SLIM_PROD_CODE,
  610. .dev_index = 0x1,
  611. .instance = 0x0,
  612. },
  613. {
  614. .manf_id = SLIM_MANF_ID_QCOM,
  615. .prod_code = 0x220,
  616. .dev_index = 0x1,
  617. .instance = 0x0,
  618. }
  619. };
  620. MODULE_DEVICE_TABLE(slim, btfm_slim_id);
  621. static struct slim_driver btfm_slim_driver = {
  622. .driver = {
  623. .name = "btfmslim-driver",
  624. .owner = THIS_MODULE,
  625. },
  626. .probe = btfm_slim_probe,
  627. .device_status = btfm_slim_status,
  628. .remove = btfm_slim_remove,
  629. .id_table = btfm_slim_id
  630. };
  631. module_slim_driver(btfm_slim_driver);
  632. MODULE_LICENSE("GPL v2");
  633. MODULE_DESCRIPTION("BTFM Slimbus Slave driver");