stp_chrdev_ant.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/types.h>
  4. #include <linux/kernel.h>
  5. #include <linux/fs.h>
  6. #include <linux/cdev.h>
  7. #include <linux/sched.h>
  8. #include <asm/current.h>
  9. #include <asm/uaccess.h>
  10. #include <linux/fcntl.h>
  11. #include <linux/poll.h>
  12. #include <linux/delay.h>
  13. #include <linux/time.h>
  14. #include "osal_typedef.h"
  15. #include "stp_exp.h"
  16. #include "wmt_exp.h"
  17. MODULE_LICENSE("Dual BSD/GPL");
  18. #define ANT_DRIVER_NAME "mtk_stp_ANT_chrdev"
  19. #define ANT_DEV_MAJOR 197 /* never used number */
  20. static PINT8 ANT_BUILT_IN_PATCH_FILE_NAME;
  21. static PINT8 ANT_BUILT_IN_PATCH_FILE_NAME_E1 = "/system/etc/firmware/ANT_RAM_CODE_E1.BIN";
  22. static PINT8 ANT_BUILT_IN_PATCH_FILE_NAME_E2 = "/system/etc/firmware/ANT_RAM_CODE_E2.BIN";
  23. #define PFX "[MTK-ANT] "
  24. #define ANT_LOG_DBG 3
  25. #define ANT_LOG_INFO 2
  26. #define ANT_LOG_WARN 1
  27. #define ANT_LOG_ERR 0
  28. #define COMBO_IOC_ANT_HWVER 6
  29. #define COMBO_IOCTL_ANT_IC_HW_VER 7
  30. #define COMBO_IOCTL_ANT_IC_FW_VER 8
  31. #define COMBO_IOCTAL_ANT_DOWNLOAD_FIRMWARE 9
  32. #define COMBO_IOC_MAGIC 0xb0
  33. #define COMBO_IOCTL_FW_ASSERT _IOWR(COMBO_IOC_MAGIC, 0, void*)
  34. #define COMBO_IOCTL_BT_IC_HW_VER _IOWR(COMBO_IOC_MAGIC, 1, int)
  35. #define COMBO_IOCTL_BT_IC_FW_VER _IOWR(COMBO_IOC_MAGIC, 2, int)
  36. static UINT32 gDbgLevel = ANT_LOG_INFO;
  37. #define ANT_DBG_FUNC(fmt, arg...) \
  38. do { if (gDbgLevel >= ANT_LOG_DBG) \
  39. pr_warn(PFX "%s: " fmt, __func__ , ##arg); \
  40. } while (0)
  41. #define ANT_INFO_FUNC(fmt, arg...) \
  42. do { if (gDbgLevel >= ANT_LOG_INFO) \
  43. pr_warn(PFX "%s: " fmt, __func__ , ##arg); \
  44. } while (0)
  45. #define ANT_WARN_FUNC(fmt, arg...) \
  46. do { if (gDbgLevel >= ANT_LOG_WARN) \
  47. pr_err(PFX "%s: " fmt, __func__ , ##arg); \
  48. } while (0)
  49. #define ANT_ERR_FUNC(fmt, arg...) \
  50. do { if (gDbgLevel >= ANT_LOG_ERR) \
  51. pr_err(PFX "%s: " fmt, __func__ , ##arg); \
  52. } while (0)
  53. #define VERSION "1.0"
  54. /* #define BT_NVRAM_CUSTOM_NAME "/data/BT_Addr" */
  55. static INT32 ANT_devs = 1; /* device count */
  56. static INT32 ANT_major = ANT_DEV_MAJOR; /* dynamic allocation */
  57. module_param(ANT_major, uint, 0);
  58. static struct cdev ANT_cdev;
  59. static UINT8 i_buf[MTKSTP_BUFFER_SIZE]; /* input buffer of read() */
  60. static UINT8 o_buf[MTKSTP_BUFFER_SIZE]; /* output buffer of write() */
  61. static struct semaphore wr_mtx, rd_mtx;
  62. static wait_queue_head_t inq; /* read queues */
  63. static DECLARE_WAIT_QUEUE_HEAD(ANT_wq);
  64. static INT32 flag;
  65. static volatile INT32 retflag;
  66. /*
  67. static unsigned char g_bt_bd_addr[10] = {0x01, 0x1a, 0xfc, 0x06, 0x00, 0x55, 0x66, 0x77, 0x88, 0x00};
  68. static unsigned char g_nvram_btdata[8];
  69. */
  70. static INT32 read_ram_code_length = 300;
  71. static int ANT_Power(unsigned long ver);
  72. /*
  73. static INT32 nvram_read(PINT8 filename, PINT8 buf, ssize_t len, INT32 offset)
  74. {
  75. struct file *fd;
  76. //ssize_t ret;
  77. INT32 retLen = -1;
  78. mm_segment_t old_fs = get_fs();
  79. set_fs(KERNEL_DS);
  80. fd = filp_open(filename, O_WRONLY | O_CREAT, 0644);
  81. if (IS_ERR(fd)) {
  82. BT_ERR_FUNC("failed to open!!\n");
  83. return -1;
  84. }
  85. do {
  86. if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) {
  87. BT_ERR_FUNC("file can not be read!!\n");
  88. break;
  89. }
  90. if (fd->f_pos != offset) {
  91. if (fd->f_op->llseek) {
  92. if (fd->f_op->llseek(fd, offset, 0) != offset) {
  93. BT_ERR_FUNC("[nvram_read] : failed to seek!!\n");
  94. break;
  95. }
  96. } else {
  97. fd->f_pos = offset;
  98. }
  99. }
  100. retLen = fd->f_op->read(fd,
  101. buf,
  102. len,
  103. &fd->f_pos);
  104. } while (false);
  105. filp_close(fd, NULL);
  106. set_fs(old_fs);
  107. return retLen;
  108. }
  109. INT32 platform_load_nvram_data(PINT8 filename, PINT8 buf, INT32 len)
  110. {
  111. //INT32 ret;
  112. BT_INFO_FUNC("platform_load_nvram_data ++ BDADDR\n");
  113. return nvram_read(filename, buf, len, 0);
  114. }
  115. */
  116. static VOID ant_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src,
  117. ENUM_WMTDRV_TYPE_T dst,
  118. ENUM_WMTMSG_TYPE_T type, PVOID buf, UINT32 sz)
  119. {
  120. /*
  121. To handle reset procedure please
  122. */
  123. ENUM_WMTRSTMSG_TYPE_T rst_msg;
  124. /*ANT_DBG_FUNC("sizeof(ENUM_WMTRSTMSG_TYPE_T) = %zd\n", sizeof(ENUM_WMTRSTMSG_TYPE_T));*/
  125. if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) {
  126. memcpy((PINT8)&rst_msg, (PINT8)buf, sz);
  127. ANT_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src,
  128. dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX);
  129. if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_ANT)
  130. && (type == WMTMSG_TYPE_RESET)) {
  131. if (rst_msg == WMTRSTMSG_RESET_START) {
  132. ANT_INFO_FUNC("ANT restart start!\n");
  133. retflag = 1;
  134. wake_up_interruptible(&inq);
  135. /*reset_start message handling */
  136. } else if (rst_msg == WMTRSTMSG_RESET_END) {
  137. ANT_INFO_FUNC("ANT restart end!\n");
  138. retflag = 2;
  139. wake_up_interruptible(&inq);
  140. /*reset_end message handling */
  141. }
  142. }
  143. } else {
  144. /*message format invalid */
  145. ANT_INFO_FUNC("message format invalid!\n");
  146. }
  147. }
  148. VOID ANT_event_cb(VOID)
  149. {
  150. ANT_DBG_FUNC("ANT_event_cb()\n");
  151. flag = 1;
  152. wake_up(&ANT_wq);
  153. /* finally, awake any reader */
  154. wake_up_interruptible(&inq); /* blocked in read() and select() */
  155. }
  156. unsigned int ANT_poll(struct file *filp, poll_table *wait)
  157. {
  158. UINT32 mask = 0;
  159. /* down(&wr_mtx); */
  160. /*
  161. * The buffer is circular; it is considered full
  162. * if "wp" is right behind "rp". "left" is 0 if the
  163. * buffer is empty, and it is "1" if it is completely full.
  164. */
  165. if (mtk_wcn_stp_is_rxqueue_empty(ANT_TASK_INDX)) {
  166. poll_wait(filp, &inq, wait);
  167. /* empty let select sleep */
  168. if ((!mtk_wcn_stp_is_rxqueue_empty(ANT_TASK_INDX)) || retflag)
  169. mask |= POLLIN | POLLRDNORM; /* readable */
  170. } else {
  171. mask |= POLLIN | POLLRDNORM; /* readable */
  172. }
  173. /* do we need condition? */
  174. mask |= POLLOUT | POLLWRNORM; /* writable */
  175. /* up(&wr_mtx); */
  176. return mask;
  177. }
  178. ssize_t ANT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
  179. {
  180. INT32 retval = 0;
  181. INT32 written = 0;
  182. down(&wr_mtx);
  183. /*ANT_DBG_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos);*/
  184. if (retflag) {
  185. if (retflag == 1) { /* reset start */
  186. retval = -88;
  187. ANT_INFO_FUNC("MT662x reset Write: start\n");
  188. } else if (retflag == 2) { /* reset end */
  189. retval = -99;
  190. ANT_INFO_FUNC("MT662x reset Write: end\n");
  191. }
  192. goto OUT;
  193. }
  194. if (count > 0) {
  195. INT32 copy_size = (count < MTKSTP_BUFFER_SIZE) ? count : MTKSTP_BUFFER_SIZE;
  196. if (copy_from_user(&o_buf[0], &buf[0], copy_size)) {
  197. retval = -EFAULT;
  198. goto OUT;
  199. }
  200. /* pr_warn("%02x ", val); */
  201. written = mtk_wcn_stp_send_data(&o_buf[0], copy_size, ANT_TASK_INDX);
  202. if (0 == written) {
  203. retval = -ENOSPC;
  204. /*no windowspace in STP is available, native process should not call BT_write with no delay at all */
  205. /*ANT_ERR_FUNC
  206. ("target packet length:%d, write success length:%d, retval = %d.\n",
  207. count, written, retval);*/
  208. } else {
  209. retval = written;
  210. }
  211. } else {
  212. retval = -EFAULT;
  213. /*ANT_ERR_FUNC("target packet length:%d is not allowed, retval = %d.\n", count,
  214. retval);*/
  215. }
  216. OUT:
  217. up(&wr_mtx);
  218. return retval;
  219. }
  220. ssize_t ANT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
  221. {
  222. INT32 retval = 0;
  223. INT32 i = 0;
  224. down(&rd_mtx);
  225. /*ANT_DBG_FUNC("ANT_read(): count %d pos %lld\n", count, *f_pos);*/
  226. if (retflag) {
  227. if (retflag == 1) { /* reset start */
  228. retval = -88;
  229. ANT_INFO_FUNC("MT662x reset Read: start\n");
  230. } else if (retflag == 2) { /* reset end */
  231. retval = -99;
  232. ANT_INFO_FUNC("MT662x reset Read: end\n");
  233. }
  234. goto OUT;
  235. }
  236. if (count > MTKSTP_BUFFER_SIZE)
  237. count = MTKSTP_BUFFER_SIZE;
  238. retval = mtk_wcn_stp_receive_data(i_buf, count, ANT_TASK_INDX);
  239. while (retval == 0) { /* got nothing, wait for STP's signal */
  240. /*If nonblocking mode, return directly O_NONBLOCK is specified during open() */
  241. if (filp->f_flags & O_NONBLOCK) {
  242. ANT_DBG_FUNC("Non-blocking ANT_read()\n");
  243. retval = -EAGAIN;
  244. goto OUT;
  245. }
  246. ANT_DBG_FUNC("ANT_read(): wait_event 1\n");
  247. wait_event(ANT_wq, flag != 0);
  248. ANT_DBG_FUNC("ANT_read(): wait_event 2\n");
  249. flag = 0;
  250. retval = mtk_wcn_stp_receive_data(i_buf, count, ANT_TASK_INDX);
  251. ANT_DBG_FUNC("ANT_read(): mtk_wcn_stp_receive_data() = %d\n", retval);
  252. }
  253. ANT_DBG_FUNC("ANT_read() read buffer is:");
  254. while (i < retval) {
  255. ANT_DBG_FUNC("[%d]:0x%x\n", i, i_buf[i]);
  256. i++;
  257. }
  258. ANT_DBG_FUNC("ANT_read(): mtk_wcn_stp_receive_data() = %d\n", retval);
  259. /* we got something from STP driver */
  260. if (copy_to_user(buf, i_buf, retval)) {
  261. retval = -EFAULT;
  262. goto OUT;
  263. }
  264. OUT:
  265. up(&rd_mtx);
  266. ANT_DBG_FUNC("ANT_read(): retval = %d\n", retval);
  267. return retval;
  268. }
  269. /* int BT_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */
  270. long ANT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  271. {
  272. INT32 retval = 0;
  273. UINT32 hw_version = 0;
  274. UINT32 fw_version = 0;
  275. MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE;
  276. ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID;
  277. ANT_DBG_FUNC("ANT_ioctl(): cmd (%d)\n", cmd);
  278. switch (cmd) {
  279. #if 0
  280. case 0: /* enable/disable STP */
  281. /* George: STP is controlled by WMT only */
  282. /* mtk_wcn_stp_enable(arg); */
  283. break;
  284. #endif
  285. case 1: /* send raw data */
  286. ANT_DBG_FUNC("ANT_ioctl(): disable raw data from ANT dev\n");
  287. retval = -EINVAL;
  288. break;
  289. case COMBO_IOC_ANT_HWVER:
  290. /*get combo hw version */
  291. hw_ver_sym = mtk_wcn_wmt_hwver_get();
  292. /*ANT_INFO_FUNC("ANT_ioctl(): get hw version = %d, sizeof(hw_ver_sym) = %d\n",
  293. hw_ver_sym, sizeof(hw_ver_sym)); */
  294. if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym)))
  295. retval = -EFAULT;
  296. break;
  297. case COMBO_IOCTL_FW_ASSERT:
  298. /* BT trigger fw assert for debug */
  299. ANT_INFO_FUNC("ANT Set fw assert......\n");
  300. /* bRet = mtk_wcn_wmt_assert(WMTDRV_TYPE_ANT, arg); temp mark */
  301. if (bRet == MTK_WCN_BOOL_TRUE) {
  302. ANT_INFO_FUNC("ANT Set fw assert OK\n");
  303. retval = 0;
  304. } else {
  305. ANT_INFO_FUNC("ANT Set fw assert Failed\n");
  306. retval = (-1000);
  307. }
  308. break;
  309. case COMBO_IOCTL_ANT_IC_HW_VER:
  310. ANT_DBG_FUNC("get hw version setup 1\n");
  311. hw_version = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER);
  312. if (copy_to_user((int __user *)arg, &hw_version, sizeof(hw_version)))
  313. retval = -EFAULT;
  314. break;
  315. case COMBO_IOCTL_ANT_IC_FW_VER:
  316. ANT_DBG_FUNC("get fw version setup 2\n");
  317. fw_version = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER);
  318. if (copy_to_user((int __user *)arg, &fw_version, sizeof(fw_version)))
  319. retval = -EFAULT;
  320. break;
  321. case COMBO_IOCTAL_ANT_DOWNLOAD_FIRMWARE:
  322. return ANT_Power(arg);
  323. default:
  324. retval = -EFAULT;
  325. ANT_DBG_FUNC("ANT_ioctl(): unknown cmd (%d)\n", cmd);
  326. break;
  327. }
  328. return retval;
  329. }
  330. long ANT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  331. {
  332. long ret;
  333. pr_warn("%s: cmd (%d)\n", __func__, cmd);
  334. ret = ANT_unlocked_ioctl(filp, cmd, arg);
  335. pr_warn("%s: cmd (%d)\n", __func__, cmd);
  336. return ret;
  337. }
  338. static INT32 ANT_DownLoad_RAM_Code(unsigned long ver)
  339. {
  340. struct file *pPatchExtFile = NULL;
  341. UINT8 pbPatchExtBin[read_ram_code_length];
  342. INT32 lFileLen = 0;
  343. INT32 download_status = 0;
  344. UINT32 transport_length = 0;
  345. INT32 download_number = 0;
  346. INT32 i = 0;
  347. mm_segment_t old_fs = get_fs();
  348. set_fs(KERNEL_DS);
  349. switch (ver) {
  350. case 1:
  351. ANT_BUILT_IN_PATCH_FILE_NAME = ANT_BUILT_IN_PATCH_FILE_NAME_E1;
  352. ANT_INFO_FUNC("download E1 patch\n");
  353. break;
  354. case 2:
  355. ANT_BUILT_IN_PATCH_FILE_NAME = ANT_BUILT_IN_PATCH_FILE_NAME_E2;
  356. ANT_INFO_FUNC("download E2 patch\n");
  357. break;
  358. default:
  359. ANT_INFO_FUNC("Can not support RAM code version:%ld!\n", ver);
  360. return 0;
  361. }
  362. pPatchExtFile = filp_open(ANT_BUILT_IN_PATCH_FILE_NAME, O_RDONLY, 0644);
  363. if ((IS_ERR(pPatchExtFile))) {
  364. ANT_ERR_FUNC("failed to open %s\r\n", ANT_BUILT_IN_PATCH_FILE_NAME);
  365. filp_close(pPatchExtFile, NULL);
  366. set_fs(old_fs);
  367. return 0;
  368. }
  369. ANT_INFO_FUNC("Open %s\r\n", ANT_BUILT_IN_PATCH_FILE_NAME);
  370. /* Set the file at end */
  371. lFileLen = pPatchExtFile->f_op->llseek(pPatchExtFile, 0, SEEK_END);
  372. /*
  373. if(pPatchExtFile->f_op->llseek(pPatchExtFile, 0, SEEK_END) != 0){
  374. ANT_ERR_FUNC("llseek ant rom code file fails errno: %d\n");
  375. return 0;
  376. }
  377. lFileLen = ftell(pPatchExtFile);
  378. */
  379. if (lFileLen < 0) {
  380. ANT_ERR_FUNC("Patch ext error len %d\n", lFileLen);
  381. filp_close(pPatchExtFile, NULL);
  382. return 0;
  383. }
  384. ANT_DBG_FUNC("Patch ext file size %d\n", lFileLen);
  385. /* rewind(pPatchExtFile); */
  386. pPatchExtFile->f_op->llseek(pPatchExtFile, 0, SEEK_SET);
  387. /* loop number */
  388. download_number = lFileLen / read_ram_code_length;
  389. ANT_DBG_FUNC("The send file loop number is %d\n", download_number);
  390. /* read down load ram code and down load it to controller side */
  391. i = 0;
  392. /* for(int i = 0 ; i <= download_number ; i ++ ){ */
  393. while ((i <= download_number)) {
  394. if (i < download_number) {
  395. ANT_DBG_FUNC("The ram code file location is %llx\n",
  396. pPatchExtFile->f_pos);
  397. if ((pPatchExtFile->f_op->
  398. read(pPatchExtFile, pbPatchExtBin,
  399. read_ram_code_length,
  400. &pPatchExtFile->f_pos)) < 0) {
  401. ANT_ERR_FUNC
  402. ("fread ant rom code file fails errno\n");
  403. filp_close(pPatchExtFile, NULL);
  404. return 0;
  405. }
  406. ANT_DBG_FUNC("The %d second read file\n", i);
  407. } else {
  408. ANT_DBG_FUNC("The ram code file location is %llx\n",
  409. pPatchExtFile->f_pos);
  410. if ((pPatchExtFile->f_op->
  411. read(pPatchExtFile, pbPatchExtBin,
  412. (lFileLen - (i * read_ram_code_length)),
  413. &pPatchExtFile->f_pos)) < 0) {
  414. ANT_ERR_FUNC("fread ant rom code file fails errno\n");
  415. filp_close(pPatchExtFile, NULL);
  416. return 0;
  417. }
  418. ANT_DBG_FUNC("The last read file\n");
  419. }
  420. /* set lengnth and status */
  421. if (0 == i) {
  422. download_status = WMT_ANT_RAM_START_PKT;
  423. transport_length = read_ram_code_length;
  424. } else if ((i != download_number) && (0 != i)) {
  425. download_status = WMT_ANT_RAM_CONTINUE_PKT;
  426. transport_length = read_ram_code_length;
  427. } else {
  428. download_status = WMT_ANT_RAM_END_PKT;
  429. transport_length = lFileLen - (i * read_ram_code_length);
  430. }
  431. if (WMT_ANT_RAM_DOWN_FAIL ==
  432. mtk_wcn_wmt_ant_ram_ctrl(WMT_ANT_RAM_DOWNLOAD, (PUINT8)(&pbPatchExtBin),
  433. transport_length, download_status)) {
  434. ANT_ERR_FUNC("Download ant rom code file fails\n");
  435. filp_close(pPatchExtFile, NULL);
  436. return 0;
  437. }
  438. i++;
  439. }
  440. /*
  441. pbPatchExtBin = (unsigned char*)malloc(lFileLen);
  442. if(pbPatchExtBin){
  443. size_t szReadLen = fread(pbPatchExtBin, 1, lFileLen, pPatchExtFile);
  444. dwPatchExtLen = szReadLen;
  445. }
  446. */
  447. filp_close(pPatchExtFile, NULL);
  448. set_fs(old_fs);
  449. return 1;
  450. }
  451. static int ANT_Power(unsigned long ver)
  452. {
  453. INT32 status = mtk_wcn_wmt_ant_ram_ctrl(WMT_ANT_RAM_GET_STATUS, 0, 0, 0);
  454. if (WMT_ANT_RAM_NOT_EXIST == status) {
  455. if (1 == ANT_DownLoad_RAM_Code(ver)) {
  456. ANT_INFO_FUNC("ANT Download RAM code is Successful\n");
  457. return 0;
  458. }
  459. ANT_INFO_FUNC("ANT Download RAM code is Fail\n");
  460. return -1;
  461. }
  462. if (WMT_ANT_RAM_EXIST == status)
  463. ANT_INFO_FUNC("ANT Fimeware side Ramcode is ready");
  464. return 0;
  465. }
  466. static int ANT_open(struct inode *inode, struct file *file)
  467. {
  468. ANT_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__,
  469. imajor(inode), iminor(inode), current->pid);
  470. if (current->pid == 1)
  471. return 0;
  472. #if 1 /* GeorgeKuo: turn on function before check stp ready */
  473. /* turn on BT */
  474. if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_ANT)) {
  475. ANT_WARN_FUNC("WMT turn on ANT fail!\n");
  476. return -ENODEV;
  477. }
  478. retflag = 0;
  479. mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_ANT, ant_cdev_rst_cb);
  480. ANT_INFO_FUNC("WMT register ANT rst cb!\n");
  481. #endif
  482. if (mtk_wcn_stp_is_ready()) {
  483. #if 0 /* GeorgeKuo: turn on function before check stp ready */
  484. /* turn on BT */
  485. if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_ANT)) {
  486. ANT_WARN_FUNC("WMT turn on ANT fail!\n");
  487. return -ENODEV;
  488. }
  489. #endif
  490. mtk_wcn_stp_set_bluez(0);
  491. ANT_DBG_FUNC("Now it's in MTK ANT Mode\n");
  492. ANT_DBG_FUNC("WMT turn on ANT OK!\n");
  493. ANT_DBG_FUNC("STP is ready!\n");
  494. #if 0
  495. platform_load_nvram_data(BT_NVRAM_CUSTOM_NAME,
  496. (char *)&g_nvram_btdata, sizeof(g_nvram_btdata));
  497. ANT_INFO_FUNC
  498. ("Read NVRAM : BD address %02x%02x%02x%02x%02x%02x Cap 0x%02x Codec 0x%02x\n",
  499. g_nvram_btdata[0], g_nvram_btdata[1], g_nvram_btdata[2], g_nvram_btdata[3],
  500. g_nvram_btdata[4], g_nvram_btdata[5], g_nvram_btdata[6], g_nvram_btdata[7]);
  501. #endif
  502. mtk_wcn_stp_register_event_cb(ANT_TASK_INDX, ANT_event_cb);
  503. ANT_DBG_FUNC("mtk_wcn_stp_register_event_cb finish\n");
  504. /* #if 0 */
  505. /* Query the RAM Code Status and download it */
  506. /* ANT_Power(); */
  507. /* #endif */
  508. } else {
  509. ANT_ERR_FUNC("STP is not ready\n");
  510. /*return error code */
  511. return -ENODEV;
  512. }
  513. /* init_MUTEX(&wr_mtx); */
  514. sema_init(&wr_mtx, 1);
  515. /* init_MUTEX(&rd_mtx); */
  516. sema_init(&rd_mtx, 1);
  517. ANT_INFO_FUNC("finish\n");
  518. return 0;
  519. }
  520. static int ANT_close(struct inode *inode, struct file *file)
  521. {
  522. ANT_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__,
  523. imajor(inode), iminor(inode), current->pid);
  524. if (current->pid == 1)
  525. return 0;
  526. retflag = 0;
  527. mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_ANT);
  528. mtk_wcn_stp_register_event_cb(ANT_TASK_INDX, NULL);
  529. if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_ANT)) {
  530. ANT_INFO_FUNC("WMT turn off ANT fail!\n");
  531. return -EIO; /* mostly, native programmer will not check this return value. */
  532. }
  533. ANT_INFO_FUNC("WMT turn off ANT OK!\n");
  534. return 0;
  535. }
  536. const struct file_operations ANT_fops = {
  537. .open = ANT_open,
  538. .release = ANT_close,
  539. .read = ANT_read,
  540. .write = ANT_write,
  541. .unlocked_ioctl = ANT_unlocked_ioctl,
  542. .compat_ioctl = ANT_compat_ioctl,
  543. .poll = ANT_poll
  544. };
  545. #if REMOVE_MK_NODE
  546. struct class *stpant_class = NULL;
  547. #endif
  548. static int ANT_init(void)
  549. {
  550. dev_t dev = MKDEV(ANT_major, 0);
  551. INT32 alloc_ret = 0;
  552. INT32 cdev_err = 0;
  553. #if REMOVE_MK_NODE
  554. struct device *stpant_dev = NULL;
  555. #endif
  556. /*static allocate chrdev */
  557. alloc_ret = register_chrdev_region(dev, 1, ANT_DRIVER_NAME);
  558. if (alloc_ret) {
  559. ANT_ERR_FUNC("fail to register chrdev\n");
  560. return alloc_ret;
  561. }
  562. cdev_init(&ANT_cdev, &ANT_fops);
  563. ANT_cdev.owner = THIS_MODULE;
  564. cdev_err = cdev_add(&ANT_cdev, dev, ANT_devs);
  565. if (cdev_err)
  566. goto error;
  567. #if REMOVE_MK_NODE /* mknod replace */
  568. stpant_class = class_create(THIS_MODULE, "stpant");
  569. if (IS_ERR(stpant_class))
  570. goto error;
  571. stpant_dev = device_create(stpant_class, NULL, dev, NULL, "stpant");
  572. if (IS_ERR(stpant_dev))
  573. goto error;
  574. #endif
  575. ANT_INFO_FUNC("%s driver(major %d) installed.\n", ANT_DRIVER_NAME, ANT_major);
  576. retflag = 0;
  577. mtk_wcn_stp_register_event_cb(ANT_TASK_INDX, NULL);
  578. /* init wait queue */
  579. init_waitqueue_head(&(inq));
  580. return 0;
  581. error:
  582. #if REMOVE_MK_NODE
  583. if (!IS_ERR(stpant_dev))
  584. device_destroy(stpant_class, dev);
  585. if (!IS_ERR(stpant_class)) {
  586. class_destroy(stpant_class);
  587. stpant_class = NULL;
  588. }
  589. #endif
  590. if (cdev_err == 0)
  591. cdev_del(&ANT_cdev);
  592. if (alloc_ret == 0)
  593. unregister_chrdev_region(dev, ANT_devs);
  594. return -1;
  595. }
  596. static void ANT_exit(void)
  597. {
  598. dev_t dev = MKDEV(ANT_major, 0);
  599. retflag = 0;
  600. mtk_wcn_stp_register_event_cb(ANT_TASK_INDX, NULL); /* unregister event callback function */
  601. #if REMOVE_MK_NODE
  602. device_destroy(stpant_class, dev);
  603. class_destroy(stpant_class);
  604. stpant_class = NULL;
  605. #endif
  606. cdev_del(&ANT_cdev);
  607. unregister_chrdev_region(dev, ANT_devs);
  608. ANT_INFO_FUNC("%s driver removed.\n", ANT_DRIVER_NAME);
  609. }
  610. #ifdef MTK_WCN_REMOVE_KERNEL_MODULE
  611. int mtk_wcn_stpant_drv_init(VOID)
  612. {
  613. return ANT_init();
  614. }
  615. EXPORT_SYMBOL(mtk_wcn_stpant_drv_init);
  616. void mtk_wcn_stpant_drv_exit(VOID)
  617. {
  618. return ANT_exit();
  619. }
  620. EXPORT_SYMBOL(mtk_wcn_stpant_drv_exit);
  621. #else
  622. module_init(ANT_init);
  623. module_exit(ANT_exit);
  624. #endif