mt6627_fm_cmd.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. #include <linux/kernel.h>
  2. #include <linux/types.h>
  3. #include "fm_typedef.h"
  4. #include "fm_dbg.h"
  5. #include "fm_err.h"
  6. #include "fm_rds.h"
  7. #include "fm_config.h"
  8. #include "fm_link.h"
  9. #include "mt6627_fm_reg.h"
  10. /* #include "mt6627_fm_link.h" */
  11. #include "mt6627_fm.h"
  12. #include "mt6627_fm_cmd.h"
  13. #include "mt6627_fm_cust_cfg.h"
  14. static fm_s32 fm_bop_write(fm_u8 addr, fm_u16 value, fm_u8 *buf, fm_s32 size)
  15. {
  16. if (size < (FM_WRITE_BASIC_OP_SIZE + 2))
  17. return -1;
  18. if (buf == NULL)
  19. return -2;
  20. buf[0] = FM_WRITE_BASIC_OP;
  21. buf[1] = FM_WRITE_BASIC_OP_SIZE;
  22. buf[2] = addr;
  23. buf[3] = (fm_u8) ((value) & 0x00FF);
  24. buf[4] = (fm_u8) ((value >> 8) & 0x00FF);
  25. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]);
  26. return FM_WRITE_BASIC_OP_SIZE + 2;
  27. }
  28. static fm_s32 fm_bop_udelay(fm_u32 value, fm_u8 *buf, fm_s32 size)
  29. {
  30. if (size < (FM_UDELAY_BASIC_OP_SIZE + 2))
  31. return -1;
  32. if (buf == NULL)
  33. return -2;
  34. buf[0] = FM_UDELAY_BASIC_OP;
  35. buf[1] = FM_UDELAY_BASIC_OP_SIZE;
  36. buf[2] = (fm_u8) ((value) & 0x000000FF);
  37. buf[3] = (fm_u8) ((value >> 8) & 0x000000FF);
  38. buf[4] = (fm_u8) ((value >> 16) & 0x000000FF);
  39. buf[5] = (fm_u8) ((value >> 24) & 0x000000FF);
  40. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
  41. return FM_UDELAY_BASIC_OP_SIZE + 2;
  42. }
  43. static fm_s32 fm_bop_rd_until(fm_u8 addr, fm_u16 mask, fm_u16 value, fm_u8 *buf, fm_s32 size)
  44. {
  45. if (size < (FM_RD_UNTIL_BASIC_OP_SIZE + 2))
  46. return -1;
  47. if (buf == NULL)
  48. return -2;
  49. buf[0] = FM_RD_UNTIL_BASIC_OP;
  50. buf[1] = FM_RD_UNTIL_BASIC_OP_SIZE;
  51. buf[2] = addr;
  52. buf[3] = (fm_u8) ((mask) & 0x00FF);
  53. buf[4] = (fm_u8) ((mask >> 8) & 0x00FF);
  54. buf[5] = (fm_u8) ((value) & 0x00FF);
  55. buf[6] = (fm_u8) ((value >> 8) & 0x00FF);
  56. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2],
  57. buf[3], buf[4], buf[5], buf[6]);
  58. return FM_RD_UNTIL_BASIC_OP_SIZE + 2;
  59. }
  60. static fm_s32 fm_bop_modify(fm_u8 addr, fm_u16 mask_and, fm_u16 mask_or, fm_u8 *buf, fm_s32 size)
  61. {
  62. if (size < (FM_MODIFY_BASIC_OP_SIZE + 2))
  63. return -1;
  64. if (buf == NULL)
  65. return -2;
  66. buf[0] = FM_MODIFY_BASIC_OP;
  67. buf[1] = FM_MODIFY_BASIC_OP_SIZE;
  68. buf[2] = addr;
  69. buf[3] = (fm_u8) ((mask_and) & 0x00FF);
  70. buf[4] = (fm_u8) ((mask_and >> 8) & 0x00FF);
  71. buf[5] = (fm_u8) ((mask_or) & 0x00FF);
  72. buf[6] = (fm_u8) ((mask_or >> 8) & 0x00FF);
  73. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2],
  74. buf[3], buf[4], buf[5], buf[6]);
  75. return FM_MODIFY_BASIC_OP_SIZE + 2;
  76. }
  77. static fm_s32 fm_bop_top_write(fm_u16 addr, fm_u32 value, fm_u8 *buf, fm_s32 size)
  78. {
  79. if (size < (FM_TOP_WRITE_BOP_SIZE + 2))
  80. return -1;
  81. if (buf == NULL)
  82. return -2;
  83. buf[0] = FM_TOP_WRITE_BASIC_OP;
  84. buf[1] = FM_TOP_WRITE_BOP_SIZE;
  85. buf[2] = 04;
  86. buf[3] = (fm_u8) ((addr) & 0x00FF);
  87. buf[4] = (fm_u8) ((addr >> 8) & 0x00FF);
  88. buf[5] = (fm_u8) ((value) & 0x00FF);
  89. buf[6] = (fm_u8) ((value >> 8) & 0x00FF);
  90. buf[7] = (fm_u8) ((value >> 16) & 0x00FF);
  91. buf[8] = (fm_u8) ((value >> 24) & 0x00FF);
  92. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1],
  93. buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]);
  94. return FM_TOP_WRITE_BOP_SIZE + 2;
  95. }
  96. static fm_s32 fm_bop_top_rd_until(fm_u16 addr, fm_u32 mask, fm_u32 value, fm_u8 *buf, fm_s32 size)
  97. {
  98. if (size < (FM_TOP_RD_UNTIL_BOP_SIZE + 2))
  99. return -1;
  100. if (buf == NULL)
  101. return -2;
  102. buf[0] = FM_TOP_RD_UNTIL_BASIC_OP;
  103. buf[1] = FM_TOP_RD_UNTIL_BOP_SIZE;
  104. buf[2] = 04;
  105. buf[3] = (fm_u8) ((addr) & 0x00FF);
  106. buf[4] = (fm_u8) ((addr >> 8) & 0x00FF);
  107. buf[5] = (fm_u8) ((mask) & 0x00FF);
  108. buf[6] = (fm_u8) ((mask >> 8) & 0x00FF);
  109. buf[7] = (fm_u8) ((mask >> 16) & 0x00FF);
  110. buf[8] = (fm_u8) ((mask >> 24) & 0x00FF);
  111. buf[9] = (fm_u8) ((value) & 0x00FF);
  112. buf[10] = (fm_u8) ((value >> 8) & 0x00FF);
  113. buf[11] = (fm_u8) ((value >> 16) & 0x00FF);
  114. buf[12] = (fm_u8) ((value >> 24) & 0x00FF);
  115. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
  116. buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9],
  117. buf[10], buf[11], buf[12]);
  118. return FM_TOP_RD_UNTIL_BOP_SIZE + 2;
  119. }
  120. /*
  121. * mt6627_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable
  122. * @buf - target buf
  123. * @buf_size - buffer size
  124. * return package size
  125. */
  126. fm_s32 mt6627_pwrup_clock_on(fm_u8 *buf, fm_s32 buf_size)
  127. {
  128. fm_s32 pkt_size = 0;
  129. fm_u16 de_emphasis;
  130. /* fm_u16 osc_freq; */
  131. if (buf_size < TX_BUF_SIZE)
  132. return -1;
  133. de_emphasis = mt6627_fm_config.rx_cfg.deemphasis;
  134. de_emphasis &= 0x0001; /* rang 0~1 */
  135. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  136. buf[1] = FM_ENABLE_OPCODE;
  137. pkt_size = 4;
  138. /* 2,turn on top clock */
  139. pkt_size += fm_bop_top_write(0xA10, 0xFFFFFFFF, &buf[pkt_size], buf_size - pkt_size); /* wr a10 ffffffff */
  140. /* 3,enable MTCMOS */
  141. pkt_size += fm_bop_top_write(0x60, 0x00000030, &buf[pkt_size], buf_size - pkt_size); /* wr 60 30 */
  142. pkt_size += fm_bop_top_write(0x60, 0x00000035, &buf[pkt_size], buf_size - pkt_size); /* wr 60 35 */
  143. pkt_size += fm_bop_top_rd_until(0x60, 0x0000000A, 0xA, &buf[pkt_size], buf_size - pkt_size);
  144. pkt_size += fm_bop_top_write(0x60, 0x00000015, &buf[pkt_size], buf_size - pkt_size); /* wr 60 15 */
  145. pkt_size += fm_bop_top_write(0x60, 0x00000005, &buf[pkt_size], buf_size - pkt_size); /* wr 60 5 */
  146. pkt_size += fm_bop_udelay(10, &buf[pkt_size], buf_size - pkt_size); /* delay 10us */
  147. pkt_size += fm_bop_top_write(0x60, 0x00000045, &buf[pkt_size], buf_size - pkt_size); /* wr 60 45 */
  148. /* 4,set CSPI fm slave dummy count */
  149. pkt_size += fm_bop_top_write(0x68, 0x0000003F, &buf[pkt_size], buf_size - pkt_size); /* wr 68 3F */
  150. /* a1 enable digital OSC */
  151. pkt_size += fm_bop_top_write(0x50, 0x00000001, &buf[pkt_size], buf_size - pkt_size); /* wr 50 1 */
  152. pkt_size += fm_bop_udelay(3000, &buf[pkt_size], buf_size - pkt_size); /* delay 3ms */
  153. /* a3 set OSC clock output to fm */
  154. pkt_size += fm_bop_top_write(0x50, 0x00000003, &buf[pkt_size], buf_size - pkt_size); /* wr 50 3 */
  155. /* a4 release HW clock gating */
  156. pkt_size += fm_bop_top_write(0x50, 0x00000007, &buf[pkt_size], buf_size - pkt_size); /* wr 50 7 */
  157. /* set I2S current driving */
  158. pkt_size += fm_bop_top_write(0x000, 0x00000000, &buf[pkt_size], buf_size - pkt_size); /* wr 0 0 */
  159. /* a5 enable DSP auto clock gating */
  160. pkt_size += fm_bop_write(0x70, 0x0040, &buf[pkt_size], buf_size - pkt_size); /* wr 70 0040 */
  161. /* a7 deemphasis setting */
  162. pkt_size += fm_bop_modify(0x61, ~DE_EMPHASIS, (de_emphasis << 12), &buf[pkt_size], buf_size - pkt_size);
  163. /* pkt_size += fm_bop_modify(0x60, OSC_FREQ_MASK, (osc_freq << 4), &buf[pkt_size], buf_size - pkt_size); */
  164. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  165. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  166. return pkt_size;
  167. }
  168. /*
  169. * mt6627_patch_download - Wholechip FM Power Up: step 3, download patch to f/w,
  170. * @buf - target buf
  171. * @buf_size - buffer size
  172. * @seg_num - total segments that this patch divided into
  173. * @seg_id - No. of Segments: segment that will now be sent
  174. * @src - patch source buffer
  175. * @seg_len - segment size: segment that will now be sent
  176. * return package size
  177. */
  178. fm_s32 mt6627_patch_download(fm_u8 *buf, fm_s32 buf_size, fm_u8 seg_num, fm_u8 seg_id,
  179. const fm_u8 *src, fm_s32 seg_len)
  180. {
  181. fm_s32 pkt_size = 0;
  182. fm_u8 *dst = NULL;
  183. if (buf_size < TX_BUF_SIZE)
  184. return -1;
  185. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  186. buf[1] = FM_PATCH_DOWNLOAD_OPCODE;
  187. pkt_size = 4;
  188. buf[pkt_size++] = seg_num;
  189. buf[pkt_size++] = seg_id;
  190. if (seg_len > (buf_size - pkt_size))
  191. return -1;
  192. dst = &buf[pkt_size];
  193. pkt_size += seg_len;
  194. /* copy patch to tx buffer */
  195. while (seg_len--) {
  196. *dst = *src;
  197. /* pr_debug("%02x ", *dst); */
  198. src++;
  199. dst++;
  200. }
  201. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  202. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  203. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2],
  204. buf[3], buf[4], buf[5], buf[6]);
  205. return pkt_size;
  206. }
  207. /*
  208. * mt6627_coeff_download - Wholechip FM Power Up: step 3,download coeff to f/w,
  209. * @buf - target buf
  210. * @buf_size - buffer size
  211. * @seg_num - total segments that this patch divided into
  212. * @seg_id - No. of Segments: segment that will now be sent
  213. * @src - patch source buffer
  214. * @seg_len - segment size: segment that will now be sent
  215. * return package size
  216. */
  217. fm_s32 mt6627_coeff_download(fm_u8 *buf, fm_s32 buf_size, fm_u8 seg_num, fm_u8 seg_id,
  218. const fm_u8 *src, fm_s32 seg_len)
  219. {
  220. fm_s32 pkt_size = 0;
  221. fm_u8 *dst = NULL;
  222. if (buf_size < TX_BUF_SIZE)
  223. return -1;
  224. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  225. buf[1] = FM_COEFF_DOWNLOAD_OPCODE;
  226. pkt_size = 4;
  227. buf[pkt_size++] = seg_num;
  228. buf[pkt_size++] = seg_id;
  229. if (seg_len > (buf_size - pkt_size))
  230. return -1;
  231. dst = &buf[pkt_size];
  232. pkt_size += seg_len;
  233. /* copy patch to tx buffer */
  234. while (seg_len--) {
  235. *dst = *src;
  236. /* pr_debug("%02x ", *dst); */
  237. src++;
  238. dst++;
  239. }
  240. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  241. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  242. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2],
  243. buf[3], buf[4], buf[5], buf[6]);
  244. return pkt_size;
  245. }
  246. #if 0
  247. /*
  248. * mt6627_hwcoeff_download - Wholechip FM Power Up: step 3,download hwcoeff to f/w,
  249. * @buf - target buf
  250. * @buf_size - buffer size
  251. * @seg_num - total segments that this patch divided into
  252. * @seg_id - No. of Segments: segment that will now be sent
  253. * @src - patch source buffer
  254. * @seg_len - segment size: segment that will now be sent
  255. * return package size
  256. */
  257. fm_s32 mt6627_hwcoeff_download(fm_u8 *buf, fm_s32 buf_size, fm_u8 seg_num, fm_u8 seg_id,
  258. const fm_u8 *src, fm_s32 seg_len)
  259. {
  260. fm_s32 pkt_size = 0;
  261. fm_u8 *dst = NULL;
  262. if (buf_size < TX_BUF_SIZE)
  263. return -1;
  264. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  265. buf[1] = FM_HWCOEFF_DOWNLOAD_OPCODE;
  266. pkt_size = 4;
  267. buf[pkt_size++] = seg_num;
  268. buf[pkt_size++] = seg_id;
  269. if (seg_len > (buf_size - pkt_size))
  270. return -1;
  271. dst = &buf[pkt_size];
  272. pkt_size += seg_len;
  273. /* copy patch to tx buffer */
  274. while (seg_len--) {
  275. *dst = *src;
  276. /* pr_debug("%02x ", *dst); */
  277. src++;
  278. dst++;
  279. }
  280. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  281. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  282. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2],
  283. buf[3], buf[4], buf[5], buf[6]);
  284. return pkt_size;
  285. }
  286. /*
  287. * mt6627_rom_download - Wholechip FM Power Up: step 3,download rom to f/w,
  288. * @buf - target buf
  289. * @buf_size - buffer size
  290. * @seg_num - total segments that this patch divided into
  291. * @seg_id - No. of Segments: segment that will now be sent
  292. * @src - patch source buffer
  293. * @seg_len - segment size: segment that will now be sent
  294. * return package size
  295. */
  296. fm_s32 mt6627_rom_download(fm_u8 *buf, fm_s32 buf_size, fm_u8 seg_num, fm_u8 seg_id, const fm_u8 *src, fm_s32 seg_len)
  297. {
  298. fm_s32 pkt_size = 0;
  299. fm_u8 *dst = NULL;
  300. if (buf_size < TX_BUF_SIZE)
  301. return -1;
  302. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  303. buf[1] = FM_ROM_DOWNLOAD_OPCODE;
  304. pkt_size = 4;
  305. buf[pkt_size++] = seg_num;
  306. buf[pkt_size++] = seg_id;
  307. if (seg_len > (buf_size - pkt_size))
  308. return -1;
  309. dst = &buf[pkt_size];
  310. pkt_size += seg_len;
  311. /* copy patch to tx buffer */
  312. while (seg_len--) {
  313. *dst = *src;
  314. /* pr_debug("%02x ", *dst); */
  315. src++;
  316. dst++;
  317. }
  318. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  319. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  320. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2],
  321. buf[3], buf[4], buf[5], buf[6]);
  322. return pkt_size;
  323. }
  324. #endif
  325. /*
  326. * mt6627_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon
  327. * @buf - target buf
  328. * @buf_size - buffer size
  329. * return package size
  330. */
  331. fm_s32 mt6627_pwrup_digital_init(fm_u8 *buf, fm_s32 buf_size)
  332. {
  333. fm_s32 pkt_size = 0;
  334. if (buf_size < TX_BUF_SIZE)
  335. return -1;
  336. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  337. buf[1] = FM_ENABLE_OPCODE;
  338. pkt_size = 4;
  339. /* FM RF&ADPLL divider setting */
  340. /* D2.1 set cell mode */
  341. /* wr 30 D3:D2 00:FDD(default),01:both.10: TDD, 11 FDD */
  342. /* pkt_size += fm_bop_modify(0x30, 0xFFF3, 0x0000, &buf[pkt_size], buf_size - pkt_size); */
  343. /* D2.2 set ADPLL divider */
  344. pkt_size += fm_bop_write(0x21, 0xE000, &buf[pkt_size], buf_size - pkt_size); /* wr 21 E000 */
  345. /* D2.3 set SDM coeff0_H */
  346. pkt_size += fm_bop_write(0xD8, 0x03F0, &buf[pkt_size], buf_size - pkt_size); /* wr D8 0x03F0 */
  347. /* D2.4 set SDM coeff0_L */
  348. pkt_size += fm_bop_write(0xD9, 0x3F04, &buf[pkt_size], buf_size - pkt_size); /* wr D9 0x3F04 */
  349. /* D2.5 set SDM coeff1_H */
  350. pkt_size += fm_bop_write(0xDA, 0x0014, &buf[pkt_size], buf_size - pkt_size); /* wr DA 0x0014 */
  351. /* D2.6 set SDM coeff1_L */
  352. pkt_size += fm_bop_write(0xDB, 0x2A38, &buf[pkt_size], buf_size - pkt_size); /* wr DB 0x2A38 */
  353. /* D2.7 set 26M clock */
  354. pkt_size += fm_bop_write(0x23, 0x4000, &buf[pkt_size], buf_size - pkt_size); /* wr 23 4000 */
  355. /* FM Digital Init: fm_rgf_maincon */
  356. /* E4 */
  357. pkt_size += fm_bop_write(0x6A, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6A 0021 */
  358. pkt_size += fm_bop_write(0x6B, 0x0021, &buf[pkt_size], buf_size - pkt_size); /* wr 6B 0021 */
  359. /* E5 */
  360. pkt_size += fm_bop_top_write(0x50, 0x0000000F, &buf[pkt_size], buf_size - pkt_size); /* wr 50 f */
  361. /* E6 */
  362. pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D1=1 */
  363. /* E7 */
  364. pkt_size += fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf[pkt_size], buf_size - pkt_size); /* wr 61 D0=0 */
  365. /* E8 */
  366. pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size); /* delay 100ms */
  367. /* E9 */
  368. pkt_size += fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf[pkt_size], buf_size - pkt_size); /* Poll 64[0~4] = 2 */
  369. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  370. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  371. return pkt_size;
  372. }
  373. /*
  374. * mt6627_pwrup_fine_tune - Wholechip FM Power Up: step 5, FM RF fine tune setting
  375. * @buf - target buf
  376. * @buf_size - buffer size
  377. * return package size
  378. */
  379. fm_s32 mt6627_pwrup_fine_tune(fm_u8 *buf, fm_s32 buf_size)
  380. {
  381. fm_s32 pkt_size = 0;
  382. if (buf_size < TX_BUF_SIZE)
  383. return -1;
  384. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  385. buf[1] = FM_ENABLE_OPCODE;
  386. pkt_size = 4;
  387. /* F1 set host control RF register */
  388. pkt_size += fm_bop_top_write(0x50, 0x00000007, &buf[pkt_size], buf_size - pkt_size);
  389. /* F2 fine tune RF setting */
  390. pkt_size += fm_bop_write(0x01, 0xBEE8, &buf[pkt_size], buf_size - pkt_size);
  391. pkt_size += fm_bop_write(0x03, 0xF6ED, &buf[pkt_size], buf_size - pkt_size);
  392. pkt_size += fm_bop_write(0x15, 0x0D80, &buf[pkt_size], buf_size - pkt_size);
  393. pkt_size += fm_bop_write(0x16, 0x0068, &buf[pkt_size], buf_size - pkt_size);
  394. pkt_size += fm_bop_write(0x17, 0x092A, &buf[pkt_size], buf_size - pkt_size);
  395. pkt_size += fm_bop_write(0x34, 0x807F, &buf[pkt_size], buf_size - pkt_size);
  396. pkt_size += fm_bop_write(0x35, 0x311E, &buf[pkt_size], buf_size - pkt_size);
  397. /* F1 set DSP control RF register */
  398. pkt_size += fm_bop_top_write(0x50, 0x0000000F, &buf[pkt_size], buf_size - pkt_size);
  399. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  400. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  401. return pkt_size;
  402. }
  403. /*
  404. * mt6627_pwrdown - Wholechip FM Power down: Digital Modem Power Down
  405. * @buf - target buf
  406. * @buf_size - buffer size
  407. * return package size
  408. */
  409. fm_s32 mt6627_pwrdown(fm_u8 *buf, fm_s32 buf_size)
  410. {
  411. fm_s32 pkt_size = 0;
  412. if (buf_size < TX_BUF_SIZE)
  413. return -1;
  414. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  415. buf[1] = FM_ENABLE_OPCODE;
  416. pkt_size = 4;
  417. /* A1:set audio output I2S Tx mode: */
  418. pkt_size += fm_bop_modify(0x9B, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  419. /* B0:Disable HW clock control */
  420. pkt_size += fm_bop_top_write(0x50, 0x330F, &buf[pkt_size], buf_size - pkt_size);
  421. /* B1:Reset ASIP */
  422. pkt_size += fm_bop_write(0x61, 0x0001, &buf[pkt_size], buf_size - pkt_size);
  423. /* B2:digital core + digital rgf reset */
  424. pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  425. pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  426. pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  427. pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  428. /* B3:Disable all clock */
  429. pkt_size += fm_bop_top_write(0x50, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  430. /* B4:Reset rgfrf */
  431. pkt_size += fm_bop_top_write(0x50, 0x4000, &buf[pkt_size], buf_size - pkt_size);
  432. pkt_size += fm_bop_top_write(0x50, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  433. /* MTCMOS power off */
  434. /* C0:disable MTCMOS */
  435. pkt_size += fm_bop_top_write(0x60, 0x0005, &buf[pkt_size], buf_size - pkt_size);
  436. pkt_size += fm_bop_top_write(0x60, 0x0015, &buf[pkt_size], buf_size - pkt_size);
  437. pkt_size += fm_bop_top_write(0x60, 0x0035, &buf[pkt_size], buf_size - pkt_size);
  438. pkt_size += fm_bop_top_write(0x60, 0x0030, &buf[pkt_size], buf_size - pkt_size);
  439. pkt_size += fm_bop_top_rd_until(0x60, 0x0000000A, 0x0, &buf[pkt_size], buf_size - pkt_size);
  440. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  441. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  442. return pkt_size;
  443. }
  444. /*
  445. * mt6627_rampdown - f/w will wait for STC_DONE interrupt
  446. * @buf - target buf
  447. * @buf_size - buffer size
  448. * return package size
  449. */
  450. fm_s32 mt6627_rampdown(fm_u8 *buf, fm_s32 buf_size)
  451. {
  452. fm_s32 pkt_size = 0;
  453. if (buf_size < TX_BUF_SIZE)
  454. return -1;
  455. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  456. buf[1] = FM_RAMPDOWN_OPCODE;
  457. pkt_size = 4;
  458. /* Clear DSP state */
  459. pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  460. /* Set DSP ramp down state */
  461. pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFFF, RAMP_DOWN, &buf[pkt_size], buf_size - pkt_size);
  462. /* @Wait for STC_DONE interrupt@ */
  463. pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size],
  464. buf_size - pkt_size);
  465. /* Clear DSP ramp down state */
  466. pkt_size += fm_bop_modify(FM_MAIN_CTRL, (~RAMP_DOWN), 0x0000, &buf[pkt_size], buf_size - pkt_size);
  467. /* Write 1 clear the STC_DONE interrupt status flag */
  468. pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);
  469. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  470. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  471. return pkt_size;
  472. }
  473. /*
  474. * mt6627_tune - execute tune action,
  475. * @buf - target buf
  476. * @buf_size - buffer size
  477. * @freq - 760 ~ 1080, 100KHz unit
  478. * return package size
  479. */
  480. fm_s32 mt6627_tune(fm_u8 *buf, fm_s32 buf_size, fm_u16 freq, fm_u16 chan_para)
  481. {
  482. /* #define FM_TUNE_USE_POLL */
  483. fm_s32 pkt_size = 0;
  484. if (buf_size < TX_BUF_SIZE)
  485. return -1;
  486. /*
  487. if (0 == fm_get_channel_space(freq)) {
  488. freq *= 10;
  489. }
  490. freq = (freq - 6400) * 2 / 10;
  491. */
  492. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  493. buf[1] = FM_TUNE_OPCODE;
  494. pkt_size = 4;
  495. /* Set desired channel & channel parameter */
  496. #ifdef FM_TUNE_USE_POLL
  497. pkt_size += fm_bop_write(0x6A, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  498. pkt_size += fm_bop_write(0x6B, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  499. #endif
  500. pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size);
  501. /* Wait for STC_DONE interrupt */
  502. #ifdef FM_TUNE_USE_POLL
  503. pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size],
  504. buf_size - pkt_size);
  505. /* Write 1 clear the STC_DONE interrupt status flag */
  506. pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);
  507. #endif
  508. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  509. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  510. return pkt_size;
  511. }
  512. /*
  513. * mt6627_full_cqi_req - execute request cqi info action,
  514. * @buf - target buf
  515. * @buf_size - buffer size
  516. * @freq - 7600 ~ 10800, freq array
  517. * @cnt - channel count
  518. * @type - request type, 1: a single channel; 2: multi channel; 3:multi channel with 100Khz step; 4: multi channel with 50Khz step
  519. *
  520. * return package size
  521. */
  522. fm_s32 mt6627_full_cqi_req(fm_u8 *buf, fm_s32 buf_size, fm_u16 *freq, fm_s32 cnt, fm_s32 type)
  523. {
  524. fm_s32 pkt_size = 0;
  525. if (buf_size < TX_BUF_SIZE)
  526. return -1;
  527. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  528. buf[1] = FM_SOFT_MUTE_TUNE_OPCODE;
  529. pkt_size = 4;
  530. switch (type) {
  531. case 1:
  532. buf[pkt_size] = 0x0001;
  533. pkt_size++;
  534. buf[pkt_size] = (fm_u8) ((*freq) & 0x00FF);
  535. pkt_size++;
  536. buf[pkt_size] = (fm_u8) ((*freq >> 8) & 0x00FF);
  537. pkt_size++;
  538. break;
  539. case 2:
  540. buf[pkt_size] = 0x0002;
  541. pkt_size++;
  542. break;
  543. case 3:
  544. buf[pkt_size] = 0x0003;
  545. pkt_size++;
  546. break;
  547. case 4:
  548. buf[pkt_size] = 0x0004;
  549. pkt_size++;
  550. break;
  551. default:
  552. buf[pkt_size] = (fm_u16) type;
  553. pkt_size++;
  554. break;
  555. }
  556. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  557. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  558. return pkt_size;
  559. }
  560. /*
  561. * mt6627_seek - execute seek action,
  562. * @buf - target buf
  563. * @buf_size - buffer size
  564. * @seekdir - 0=seek up, 1=seek down
  565. * @space - step, 50KHz:001, 100KHz:010, 200KHz:100
  566. * @max_freq - upper bound
  567. * @min_freq - lower bound
  568. * return package size
  569. */
  570. fm_s32 mt6627_seek(fm_u8 *buf, fm_s32 buf_size, fm_u16 seekdir, fm_u16 space, fm_u16 max_freq, fm_u16 min_freq)
  571. {
  572. fm_s32 pkt_size = 0;
  573. if (buf_size < TX_BUF_SIZE)
  574. return -1;
  575. if (0 == fm_get_channel_space(max_freq))
  576. max_freq *= 10;
  577. if (0 == fm_get_channel_space(min_freq))
  578. min_freq *= 10;
  579. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  580. buf[1] = FM_SEEK_OPCODE;
  581. pkt_size = 4;
  582. /* Program seek direction */
  583. if (seekdir == 0)
  584. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFBFF, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  585. else
  586. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFBFF, 0x0400, &buf[pkt_size], buf_size - pkt_size);
  587. /* Program scan channel spacing */
  588. if (space == 1)
  589. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x1000, &buf[pkt_size], buf_size - pkt_size);
  590. else if (space == 2)
  591. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x2000, &buf[pkt_size], buf_size - pkt_size);
  592. else if (space == 4)
  593. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x4000, &buf[pkt_size], buf_size - pkt_size);
  594. /* enable wrap , if it is not auto scan function, 0x66[11] 0=no wrarp, 1=wrap */
  595. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xF7FF, 0x0800, &buf[pkt_size], buf_size - pkt_size);
  596. /* 0x66[9:0] freq upper bound */
  597. max_freq = (max_freq - 6400) * 2 / 10;
  598. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFC00, max_freq, &buf[pkt_size], buf_size - pkt_size);
  599. /* 0x67[9:0] freq lower bound */
  600. min_freq = (min_freq - 6400) * 2 / 10;
  601. pkt_size += fm_bop_modify(FM_MAIN_CFG2, 0xFC00, min_freq, &buf[pkt_size], buf_size - pkt_size);
  602. /* Enable hardware controlled seeking sequence */
  603. pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, SEEK, &buf[pkt_size], buf_size - pkt_size);
  604. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  605. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  606. return pkt_size;
  607. }
  608. /*
  609. * mt6627_scan - execute scan action,
  610. * @buf - target buf
  611. * @buf_size - buffer size
  612. * @scandir - 0=seek up, 1=seek down
  613. * @space - step, 50KHz:001, 100KHz:010, 200KHz:100
  614. * @max_freq - upper bound
  615. * @min_freq - lower bound
  616. * return package size
  617. */
  618. fm_s32 mt6627_scan(fm_u8 *buf, fm_s32 buf_size, fm_u16 scandir, fm_u16 space, fm_u16 max_freq, fm_u16 min_freq)
  619. {
  620. fm_s32 pkt_size = 0;
  621. if (buf_size < TX_BUF_SIZE)
  622. return -1;
  623. if (0 == fm_get_channel_space(max_freq))
  624. max_freq *= 10;
  625. if (0 == fm_get_channel_space(min_freq))
  626. min_freq *= 10;
  627. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  628. buf[1] = FM_SCAN_OPCODE;
  629. pkt_size = 4;
  630. /* Program seek direction */
  631. if (scandir == 0)
  632. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFBFF, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  633. /* 0x66[10] = 0, seek up */
  634. else
  635. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFFFF, 0x0400, &buf[pkt_size], buf_size - pkt_size);
  636. /* 0x66[10] = 1, seek down */
  637. /* Program scan channel spacing */
  638. if (space == 1) {
  639. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x1000, &buf[pkt_size], buf_size - pkt_size);
  640. /* clear 0x66[14:12] then 0x66[14:12]=001 */
  641. } else if (space == 2) {
  642. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x2000, &buf[pkt_size], buf_size - pkt_size);
  643. /* clear 0x66[14:12] then 0x66[14:12]=010 */
  644. } else if (space == 4) {
  645. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x4000, &buf[pkt_size], buf_size - pkt_size);
  646. /* clear 0x66[14:12] then 0x66[14:12]=100 */
  647. }
  648. /* disable wrap , if it is auto scan function, 0x66[11] 0=no wrarp, 1=wrap */
  649. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xF7FF, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  650. /* 0x66[11] = 0, no wrap */
  651. /* 0x66[9:0] freq upper bound */
  652. max_freq = (max_freq - 6400) * 2 / 10;
  653. pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFC00, max_freq, &buf[pkt_size], buf_size - pkt_size);
  654. /* 0x67[9:0] freq lower bound */
  655. min_freq = (min_freq - 6400) * 2 / 10;
  656. pkt_size += fm_bop_modify(FM_MAIN_CFG2, 0xFC00, min_freq, &buf[pkt_size], buf_size - pkt_size);
  657. /* Enable hardware controlled scanning sequence */
  658. pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, SCAN, &buf[pkt_size], buf_size - pkt_size);
  659. /* 0x63[1] = 1 */
  660. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  661. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  662. return pkt_size;
  663. }
  664. fm_s32 mt6627_cqi_get(fm_u8 *buf, fm_s32 buf_size)
  665. {
  666. fm_s32 pkt_size = 0;
  667. if (buf_size < TX_BUF_SIZE)
  668. return -1;
  669. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  670. buf[1] = FM_SCAN_OPCODE;
  671. pkt_size = 4;
  672. pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size);
  673. /* wr 63 bit0~2 0 */
  674. pkt_size += fm_bop_modify(FM_MAIN_CTRL, ~CQI_READ, CQI_READ, &buf[pkt_size], buf_size - pkt_size);
  675. /* wr 63 bit3 1 */
  676. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  677. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  678. return pkt_size;
  679. }
  680. fm_s32 mt6627_get_reg(fm_u8 *buf, fm_s32 buf_size, fm_u8 addr)
  681. {
  682. if (buf_size < TX_BUF_SIZE)
  683. return -1;
  684. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  685. buf[1] = FSPI_READ_OPCODE;
  686. buf[2] = 0x01;
  687. buf[3] = 0x00;
  688. buf[4] = addr;
  689. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]);
  690. return 5;
  691. }
  692. fm_s32 mt6627_set_reg(fm_u8 *buf, fm_s32 buf_size, fm_u8 addr, fm_u16 value)
  693. {
  694. if (buf_size < TX_BUF_SIZE)
  695. return -1;
  696. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  697. buf[1] = FSPI_WRITE_OPCODE;
  698. buf[2] = 0x03;
  699. buf[3] = 0x00;
  700. buf[4] = addr;
  701. buf[5] = (fm_u8) ((value) & 0x00FF);
  702. buf[6] = (fm_u8) ((value >> 8) & 0x00FF);
  703. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2],
  704. buf[3], buf[4], buf[5], buf[6]);
  705. return 7;
  706. }
  707. fm_s32 mt6627_set_bits_reg(fm_u8 *buf, fm_s32 buf_size, fm_u8 addr, fm_u16 bits, fm_u16 mask)
  708. {
  709. fm_s32 pkt_size = 0;
  710. if (buf_size < TX_BUF_SIZE)
  711. return -1;
  712. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  713. buf[1] = 0x11; /* 0x11 this opcode won't be parsed as an opcode, so set here as spcial case. */
  714. pkt_size = 4;
  715. pkt_size += fm_bop_modify(addr, mask, bits, &buf[pkt_size], buf_size - pkt_size);
  716. buf[2] = (fm_u8) ((pkt_size - 4) & 0x00FF);
  717. buf[3] = (fm_u8) (((pkt_size - 4) >> 8) & 0x00FF);
  718. return pkt_size;
  719. }
  720. /*top register read*/
  721. fm_s32 mt6627_top_get_reg(fm_u8 *buf, fm_s32 buf_size, fm_u16 addr)
  722. {
  723. if (buf_size < TX_BUF_SIZE)
  724. return -1;
  725. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  726. buf[1] = CSPI_READ_OPCODE;
  727. buf[2] = 0x03;
  728. buf[3] = 0x00;
  729. buf[4] = 0x04; /* top 04,fm 02 */
  730. buf[5] = (fm_u8) ((addr) & 0x00FF);
  731. buf[6] = (fm_u8) ((addr >> 8) & 0x00FF);
  732. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2],
  733. buf[3], buf[4], buf[5], buf[6]);
  734. return 7;
  735. }
  736. fm_s32 mt6627_top_set_reg(fm_u8 *buf, fm_s32 buf_size, fm_u16 addr, fm_u32 value)
  737. {
  738. if (buf_size < TX_BUF_SIZE)
  739. return -1;
  740. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  741. buf[1] = CSPI_WRITE_OPCODE;
  742. buf[2] = 0x07;
  743. buf[3] = 0x00;
  744. buf[4] = 0x04; /* top 04,fm 02 */
  745. buf[5] = (fm_u8) ((addr) & 0x00FF);
  746. buf[6] = (fm_u8) ((addr >> 8) & 0x00FF);
  747. buf[7] = (fm_u8) ((value) & 0x00FF);
  748. buf[8] = (fm_u8) ((value >> 8) & 0x00FF);
  749. buf[9] = (fm_u8) ((value >> 16) & 0x00FF);
  750. buf[10] = (fm_u8) ((value >> 24) & 0x00FF);
  751. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0],
  752. buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10]);
  753. return 11;
  754. }
  755. /*host register read*/
  756. fm_s32 mt6627_host_get_reg(fm_u8 *buf, fm_s32 buf_size, fm_u32 addr)
  757. {
  758. if (buf_size < TX_BUF_SIZE)
  759. return -1;
  760. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  761. buf[1] = FM_HOST_READ_OPCODE;
  762. buf[2] = 0x04;
  763. buf[3] = 0x00;
  764. buf[4] = (fm_u8) ((addr) & 0x00FF);
  765. buf[5] = (fm_u8) ((addr >> 8) & 0x00FF);
  766. buf[6] = (fm_u8) ((addr >> 16) & 0x00FF);
  767. buf[7] = (fm_u8) ((addr >> 24) & 0x00FF);
  768. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2],
  769. buf[3], buf[4], buf[5], buf[6], buf[7]);
  770. return 8;
  771. }
  772. fm_s32 mt6627_host_set_reg(fm_u8 *buf, fm_s32 buf_size, fm_u32 addr, fm_u32 value)
  773. {
  774. if (buf_size < TX_BUF_SIZE)
  775. return -1;
  776. buf[0] = FM_TASK_COMMAND_PKT_TYPE;
  777. buf[1] = FM_HOST_WRITE_OPCODE;
  778. buf[2] = 0x08;
  779. buf[3] = 0x00;
  780. buf[4] = (fm_u8) ((addr) & 0x00FF);
  781. buf[5] = (fm_u8) ((addr >> 8) & 0x00FF);
  782. buf[6] = (fm_u8) ((addr >> 16) & 0x00FF);
  783. buf[7] = (fm_u8) ((addr >> 24) & 0x00FF);
  784. buf[8] = (fm_u8) ((value) & 0x00FF);
  785. buf[9] = (fm_u8) ((value >> 8) & 0x00FF);
  786. buf[10] = (fm_u8) ((value >> 16) & 0x00FF);
  787. buf[11] = (fm_u8) ((value >> 24) & 0x00FF);
  788. WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
  789. buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
  790. return 12;
  791. }