1 #include <linux/kernel.h>
2 #include <linux/types.h>
4 #include "fm_typedef.h"
11 #include "mt6627_fm_reg.h"
12 /* #include "mt6627_fm_link.h" */
13 #include "mt6627_fm.h"
14 #include "mt6627_fm_cmd.h"
15 #include "mt6627_fm_cust_cfg.h"
17 extern fm_cust_cfg mt6627_fm_config
;
19 static fm_s32
fm_bop_write(fm_u8 addr
, fm_u16 value
, fm_u8
*buf
, fm_s32 size
)
21 if (size
< (FM_WRITE_BASIC_OP_SIZE
+ 2)) {
29 buf
[0] = FM_WRITE_BASIC_OP
;
30 buf
[1] = FM_WRITE_BASIC_OP_SIZE
;
32 buf
[3] = (fm_u8
) ((value
) & 0x00FF);
33 buf
[4] = (fm_u8
) ((value
>> 8) & 0x00FF);
35 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2], buf
[3],
38 return (FM_WRITE_BASIC_OP_SIZE
+ 2);
42 static fm_s32
fm_bop_udelay(fm_u32 value
, fm_u8
*buf
, fm_s32 size
)
44 if (size
< (FM_UDELAY_BASIC_OP_SIZE
+ 2)) {
52 buf
[0] = FM_UDELAY_BASIC_OP
;
53 buf
[1] = FM_UDELAY_BASIC_OP_SIZE
;
54 buf
[2] = (fm_u8
) ((value
) & 0x000000FF);
55 buf
[3] = (fm_u8
) ((value
>> 8) & 0x000000FF);
56 buf
[4] = (fm_u8
) ((value
>> 16) & 0x000000FF);
57 buf
[5] = (fm_u8
) ((value
>> 24) & 0x000000FF);
59 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2], buf
[3],
62 return (FM_UDELAY_BASIC_OP_SIZE
+ 2);
66 static fm_s32
fm_bop_rd_until(fm_u8 addr
, fm_u16 mask
, fm_u16 value
, fm_u8
*buf
, fm_s32 size
)
68 if (size
< (FM_RD_UNTIL_BASIC_OP_SIZE
+ 2)) {
76 buf
[0] = FM_RD_UNTIL_BASIC_OP
;
77 buf
[1] = FM_RD_UNTIL_BASIC_OP_SIZE
;
79 buf
[3] = (fm_u8
) ((mask
) & 0x00FF);
80 buf
[4] = (fm_u8
) ((mask
>> 8) & 0x00FF);
81 buf
[5] = (fm_u8
) ((value
) & 0x00FF);
82 buf
[6] = (fm_u8
) ((value
>> 8) & 0x00FF);
84 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2],
85 buf
[3], buf
[4], buf
[5], buf
[6]);
87 return (FM_RD_UNTIL_BASIC_OP_SIZE
+ 2);
91 static fm_s32
fm_bop_modify(fm_u8 addr
, fm_u16 mask_and
, fm_u16 mask_or
, fm_u8
*buf
, fm_s32 size
)
93 if (size
< (FM_MODIFY_BASIC_OP_SIZE
+ 2)) {
101 buf
[0] = FM_MODIFY_BASIC_OP
;
102 buf
[1] = FM_MODIFY_BASIC_OP_SIZE
;
104 buf
[3] = (fm_u8
) ((mask_and
) & 0x00FF);
105 buf
[4] = (fm_u8
) ((mask_and
>> 8) & 0x00FF);
106 buf
[5] = (fm_u8
) ((mask_or
) & 0x00FF);
107 buf
[6] = (fm_u8
) ((mask_or
>> 8) & 0x00FF);
109 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2],
110 buf
[3], buf
[4], buf
[5], buf
[6]);
112 return (FM_MODIFY_BASIC_OP_SIZE
+ 2);
116 static fm_s32
fm_bop_top_write(fm_u16 addr
, fm_u32 value
, fm_u8
*buf
, fm_s32 size
)
118 if (size
< (FM_TOP_WRITE_BOP_SIZE
+ 2)) {
126 buf
[0] = FM_TOP_WRITE_BASIC_OP
;
127 buf
[1] = FM_TOP_WRITE_BOP_SIZE
;
129 buf
[3] = (fm_u8
) ((addr
) & 0x00FF);
130 buf
[4] = (fm_u8
) ((addr
>> 8) & 0x00FF);
131 buf
[5] = (fm_u8
) ((value
) & 0x00FF);
132 buf
[6] = (fm_u8
) ((value
>> 8) & 0x00FF);
133 buf
[7] = (fm_u8
) ((value
>> 16) & 0x00FF);
134 buf
[8] = (fm_u8
) ((value
>> 24) & 0x00FF);
136 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1],
137 buf
[2], buf
[3], buf
[4], buf
[5], buf
[6], buf
[7], buf
[8]);
139 return (FM_TOP_WRITE_BOP_SIZE
+ 2);
143 static fm_s32
fm_bop_top_rd_until(fm_u16 addr
, fm_u32 mask
, fm_u32 value
, fm_u8
*buf
, fm_s32 size
)
145 if (size
< (FM_TOP_RD_UNTIL_BOP_SIZE
+ 2)) {
153 buf
[0] = FM_TOP_RD_UNTIL_BASIC_OP
;
154 buf
[1] = FM_TOP_RD_UNTIL_BOP_SIZE
;
156 buf
[3] = (fm_u8
) ((addr
) & 0x00FF);
157 buf
[4] = (fm_u8
) ((addr
>> 8) & 0x00FF);
158 buf
[5] = (fm_u8
) ((mask
) & 0x00FF);
159 buf
[6] = (fm_u8
) ((mask
>> 8) & 0x00FF);
160 buf
[7] = (fm_u8
) ((mask
>> 16) & 0x00FF);
161 buf
[8] = (fm_u8
) ((mask
>> 24) & 0x00FF);
162 buf
[9] = (fm_u8
) ((value
) & 0x00FF);
163 buf
[10] = (fm_u8
) ((value
>> 8) & 0x00FF);
164 buf
[11] = (fm_u8
) ((value
>> 16) & 0x00FF);
165 buf
[12] = (fm_u8
) ((value
>> 24) & 0x00FF);
167 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
168 buf
[0], buf
[1], buf
[2], buf
[3], buf
[4], buf
[5], buf
[6], buf
[7], buf
[8], buf
[9],
169 buf
[10], buf
[11], buf
[12]);
171 return (FM_TOP_RD_UNTIL_BOP_SIZE
+ 2);
175 * mt6627_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable
177 * @buf_size - buffer size
178 * return package size
180 fm_s32
mt6627_pwrup_clock_on(fm_u8
*buf
, fm_s32 buf_size
)
184 /* fm_u16 osc_freq; */
186 if (buf_size
< TX_BUF_SIZE
) {
190 de_emphasis
= mt6627_fm_config
.rx_cfg
.deemphasis
; /* MT6627fm_cust_config_fetch(FM_CFG_RX_DEEMPHASIS); */
191 de_emphasis
&= 0x0001; /* rang 0~1 */
192 /* osc_freq = mt6627_fm_config.rx_cfg.osc_freq;//MT6628fm_cust_config_fetch(FM_CFG_RX_OSC_FREQ); */
193 /* osc_freq &= 0x0007; //rang 0~5 */
195 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
196 buf
[1] = FM_ENABLE_OPCODE
;
199 /* 2,turn on top clock */
200 pkt_size
+= fm_bop_top_write(0xA10, 0xFFFFFFFF, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr a10 ffffffff */
201 /* 3,enable MTCMOS */
202 pkt_size
+= fm_bop_top_write(0x60, 0x00000030, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 60 30 */
203 pkt_size
+= fm_bop_top_write(0x60, 0x00000035, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 60 35 */
204 pkt_size
+= fm_bop_top_rd_until(0x60, 0x0000000A, 0xA, &buf
[pkt_size
], buf_size
- pkt_size
); /* Poll 60[1]=1,[3]= 1 */
205 pkt_size
+= fm_bop_top_write(0x60, 0x00000015, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 60 15 */
206 pkt_size
+= fm_bop_top_write(0x60, 0x00000005, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 60 5 */
207 pkt_size
+= fm_bop_udelay(10, &buf
[pkt_size
], buf_size
- pkt_size
); /* delay 10us */
208 pkt_size
+= fm_bop_top_write(0x60, 0x00000045, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 60 45 */
209 /* 4,set CSPI fm slave dummy count */
210 pkt_size
+= fm_bop_top_write(0x68, 0x0000003F, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 68 3F */
212 /* a1 enable digital OSC */
213 pkt_size
+= fm_bop_top_write(0x50, 0x00000001, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 50 1 */
214 pkt_size
+= fm_bop_udelay(3000, &buf
[pkt_size
], buf_size
- pkt_size
); /* delay 3ms */
215 /* a3 set OSC clock output to fm */
216 pkt_size
+= fm_bop_top_write(0x50, 0x00000003, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 50 3 */
217 /* a4 release HW clock gating */
218 pkt_size
+= fm_bop_top_write(0x50, 0x00000007, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 50 7 */
219 /* set I2S current driving */
220 pkt_size
+= fm_bop_top_write(0x000, 0x00000000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 0 0 */
221 /* a5 enable DSP auto clock gating */
222 pkt_size
+= fm_bop_write(0x70, 0x0040, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 70 0040 */
223 /* a7 deemphasis setting */
225 fm_bop_modify(0x61, ~DE_EMPHASIS
, (de_emphasis
<< 12), &buf
[pkt_size
],
226 buf_size
- pkt_size
);
228 /* pkt_size += fm_bop_modify(0x60, OSC_FREQ_MASK, (osc_freq << 4), &buf[pkt_size], buf_size - pkt_size); */
230 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
231 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
238 * mt6627_patch_download - Wholechip FM Power Up: step 3, download patch to f/w,
240 * @buf_size - buffer size
241 * @seg_num - total segments that this patch divided into
242 * @seg_id - No. of Segments: segment that will now be sent
243 * @src - patch source buffer
244 * @seg_len - segment size: segment that will now be sent
245 * return package size
247 fm_s32
mt6627_patch_download(fm_u8
*buf
, fm_s32 buf_size
, fm_u8 seg_num
, fm_u8 seg_id
,
248 const fm_u8
*src
, fm_s32 seg_len
)
253 if (buf_size
< TX_BUF_SIZE
) {
257 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
258 buf
[1] = FM_PATCH_DOWNLOAD_OPCODE
;
261 buf
[pkt_size
++] = seg_num
;
262 buf
[pkt_size
++] = seg_id
;
264 if (seg_len
> (buf_size
- pkt_size
)) {
268 dst
= &buf
[pkt_size
];
271 /* copy patch to tx buffer */
274 /* pr_debug("%02x ", *dst); */
279 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
280 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
281 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2],
282 buf
[3], buf
[4], buf
[5], buf
[6]);
289 * mt6627_coeff_download - Wholechip FM Power Up: step 3,download coeff to f/w,
291 * @buf_size - buffer size
292 * @seg_num - total segments that this patch divided into
293 * @seg_id - No. of Segments: segment that will now be sent
294 * @src - patch source buffer
295 * @seg_len - segment size: segment that will now be sent
296 * return package size
298 fm_s32
mt6627_coeff_download(fm_u8
*buf
, fm_s32 buf_size
, fm_u8 seg_num
, fm_u8 seg_id
,
299 const fm_u8
*src
, fm_s32 seg_len
)
304 if (buf_size
< TX_BUF_SIZE
) {
308 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
309 buf
[1] = FM_COEFF_DOWNLOAD_OPCODE
;
312 buf
[pkt_size
++] = seg_num
;
313 buf
[pkt_size
++] = seg_id
;
315 if (seg_len
> (buf_size
- pkt_size
)) {
319 dst
= &buf
[pkt_size
];
322 /* copy patch to tx buffer */
325 /* pr_debug("%02x ", *dst); */
330 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
331 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
332 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2],
333 buf
[3], buf
[4], buf
[5], buf
[6]);
340 * mt6627_hwcoeff_download - Wholechip FM Power Up: step 3,download hwcoeff to f/w,
342 * @buf_size - buffer size
343 * @seg_num - total segments that this patch divided into
344 * @seg_id - No. of Segments: segment that will now be sent
345 * @src - patch source buffer
346 * @seg_len - segment size: segment that will now be sent
347 * return package size
349 fm_s32
mt6627_hwcoeff_download(fm_u8
*buf
, fm_s32 buf_size
, fm_u8 seg_num
, fm_u8 seg_id
,
350 const fm_u8
*src
, fm_s32 seg_len
)
355 if (buf_size
< TX_BUF_SIZE
) {
359 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
360 buf
[1] = FM_HWCOEFF_DOWNLOAD_OPCODE
;
363 buf
[pkt_size
++] = seg_num
;
364 buf
[pkt_size
++] = seg_id
;
366 if (seg_len
> (buf_size
- pkt_size
)) {
370 dst
= &buf
[pkt_size
];
373 /* copy patch to tx buffer */
376 /* pr_debug("%02x ", *dst); */
381 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
382 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
383 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2],
384 buf
[3], buf
[4], buf
[5], buf
[6]);
391 * mt6627_rom_download - Wholechip FM Power Up: step 3,download rom to f/w,
393 * @buf_size - buffer size
394 * @seg_num - total segments that this patch divided into
395 * @seg_id - No. of Segments: segment that will now be sent
396 * @src - patch source buffer
397 * @seg_len - segment size: segment that will now be sent
398 * return package size
400 fm_s32
mt6627_rom_download(fm_u8
*buf
, fm_s32 buf_size
, fm_u8 seg_num
, fm_u8 seg_id
,
401 const fm_u8
*src
, fm_s32 seg_len
)
406 if (buf_size
< TX_BUF_SIZE
) {
410 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
411 buf
[1] = FM_ROM_DOWNLOAD_OPCODE
;
414 buf
[pkt_size
++] = seg_num
;
415 buf
[pkt_size
++] = seg_id
;
417 if (seg_len
> (buf_size
- pkt_size
)) {
421 dst
= &buf
[pkt_size
];
424 /* copy patch to tx buffer */
427 /* pr_debug("%02x ", *dst); */
432 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
433 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
434 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2],
435 buf
[3], buf
[4], buf
[5], buf
[6]);
442 * mt6627_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon
444 * @buf_size - buffer size
445 * return package size
447 fm_s32
mt6627_pwrup_digital_init(fm_u8
*buf
, fm_s32 buf_size
)
451 if (buf_size
< TX_BUF_SIZE
) {
455 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
456 buf
[1] = FM_ENABLE_OPCODE
;
458 /* FM RF&ADPLL divider setting */
459 /* D2.1 set cell mode */
460 /* wr 30 D3:D2 00:FDD(default),01:both.10: TDD, 11 FDD */
461 /* pkt_size += fm_bop_modify(0x30, 0xFFF3, 0x0000, &buf[pkt_size], buf_size - pkt_size); */
462 /* D2.2 set ADPLL divider */
463 pkt_size
+= fm_bop_write(0x21, 0xE000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 21 E000 */
464 /* D2.3 set SDM coeff0_H */
465 pkt_size
+= fm_bop_write(0xD8, 0x03F0, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr D8 0x03F0 */
466 /* D2.4 set SDM coeff0_L */
467 pkt_size
+= fm_bop_write(0xD9, 0x3F04, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr D9 0x3F04 */
468 /* D2.5 set SDM coeff1_H */
469 pkt_size
+= fm_bop_write(0xDA, 0x0014, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr DA 0x0014 */
470 /* D2.6 set SDM coeff1_L */
471 pkt_size
+= fm_bop_write(0xDB, 0x2A38, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr DB 0x2A38 */
472 /* D2.7 set 26M clock */
473 pkt_size
+= fm_bop_write(0x23, 0x4000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 23 4000 */
475 /* FM Digital Init: fm_rgf_maincon */
477 pkt_size
+= fm_bop_write(0x6A, 0x0021, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 6A 0021 */
478 pkt_size
+= fm_bop_write(0x6B, 0x0021, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 6B 0021 */
480 pkt_size
+= fm_bop_top_write(0x50, 0x0000000F, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 50 f */
482 pkt_size
+= fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 61 D1=1 */
484 pkt_size
+= fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 61 D0=0 */
486 pkt_size
+= fm_bop_udelay(100000, &buf
[pkt_size
], buf_size
- pkt_size
); /* delay 100ms */
488 pkt_size
+= fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf
[pkt_size
], buf_size
- pkt_size
); /* Poll 64[0~4] = 2 */
490 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
491 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
497 * mt6627_pwrup_fine_tune - Wholechip FM Power Up: step 5, FM RF fine tune setting
499 * @buf_size - buffer size
500 * return package size
502 fm_s32
mt6627_pwrup_fine_tune(fm_u8
*buf
, fm_s32 buf_size
)
506 if (buf_size
< TX_BUF_SIZE
) {
510 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
511 buf
[1] = FM_ENABLE_OPCODE
;
514 /* F1 set host control RF register */
515 pkt_size
+= fm_bop_top_write(0x50, 0x00000007, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 50 7 */
516 /* F2 fine tune RF setting */
517 pkt_size
+= fm_bop_write(0x01, 0xBEE8, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 01 0xBEE8 */
518 pkt_size
+= fm_bop_write(0x03, 0xF6ED, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 03 0xF6ED mdy 0315 version */
519 pkt_size
+= fm_bop_write(0x15, 0x0D80, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 15 0x0D80 */
520 pkt_size
+= fm_bop_write(0x16, 0x0068, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 16 0x0068 */
521 pkt_size
+= fm_bop_write(0x17, 0x092A, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 17 0x092A */
522 pkt_size
+= fm_bop_write(0x34, 0x807F, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 34 0x807F */
523 pkt_size
+= fm_bop_write(0x35, 0x311E, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 35 0x311E */
524 /* F1 set DSP control RF register */
525 pkt_size
+= fm_bop_top_write(0x50, 0x0000000F, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 50 F */
527 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
528 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
535 * mt6627_pwrdown - Wholechip FM Power down: Digital Modem Power Down
537 * @buf_size - buffer size
538 * return package size
540 fm_s32
mt6627_pwrdown(fm_u8
*buf
, fm_s32 buf_size
)
544 if (buf_size
< TX_BUF_SIZE
) {
548 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
549 buf
[1] = FM_ENABLE_OPCODE
;
551 /* A1:set audio output I2S Tx mode: */
552 pkt_size
+= fm_bop_modify(0x9B, 0xFFF8, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 9B[0~2] 0 */
554 /* B0:Disable HW clock control */
555 pkt_size
+= fm_bop_top_write(0x50, 0x330F, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr top50 330F */
557 pkt_size
+= fm_bop_write(0x61, 0x0001, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 61 0001 */
558 /* B2:digital core + digital rgf reset */
559 pkt_size
+= fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 6E[0~2] 0 */
560 pkt_size
+= fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 6E[0~2] 0 */
561 pkt_size
+= fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 6E[0~2] 0 */
562 pkt_size
+= fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 6E[0~2] 0 */
563 /* B3:Disable all clock */
564 pkt_size
+= fm_bop_top_write(0x50, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr top50 0000 */
566 pkt_size
+= fm_bop_top_write(0x50, 0x4000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr top50 4000 */
567 pkt_size
+= fm_bop_top_write(0x50, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr top50 0000 */
568 /* MTCMOS power off */
569 /* C0:disable MTCMOS */
570 pkt_size
+= fm_bop_top_write(0x60, 0x0005, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr top60 0005 */
571 pkt_size
+= fm_bop_top_write(0x60, 0x0015, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr top60 0015 */
572 pkt_size
+= fm_bop_top_write(0x60, 0x0035, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr top60 0035 */
573 pkt_size
+= fm_bop_top_write(0x60, 0x0030, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr top60 0030 */
574 pkt_size
+= fm_bop_top_rd_until(0x60, 0x0000000A, 0x0, &buf
[pkt_size
], buf_size
- pkt_size
); /* Poll 60[1]=0,[3]= 0 */
576 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
577 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
584 * mt6627_rampdown - f/w will wait for STC_DONE interrupt
586 * @buf_size - buffer size
587 * return package size
589 fm_s32
mt6627_rampdown(fm_u8
*buf
, fm_s32 buf_size
)
593 if (buf_size
< TX_BUF_SIZE
) {
597 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
598 buf
[1] = FM_RAMPDOWN_OPCODE
;
601 /* Clear DSP state */
602 pkt_size
+= fm_bop_modify(FM_MAIN_CTRL
, 0xFFF0, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 63[3:0] = 0 */
603 /* Set DSP ramp down state */
604 pkt_size
+= fm_bop_modify(FM_MAIN_CTRL
, 0xFFFF, RAMP_DOWN
, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 63[8] = 1 */
605 /* @Wait for STC_DONE interrupt@ */
606 pkt_size
+= fm_bop_rd_until(FM_MAIN_INTR
, FM_INTR_STC_DONE
, FM_INTR_STC_DONE
, &buf
[pkt_size
], buf_size
- pkt_size
); /* Poll 69[0] = b'1 */
607 /* Clear DSP ramp down state */
608 pkt_size
+= fm_bop_modify(FM_MAIN_CTRL
, (~RAMP_DOWN
), 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 63[8] = 0 */
609 /* Write 1 clear the STC_DONE interrupt status flag */
610 pkt_size
+= fm_bop_modify(FM_MAIN_INTR
, 0xFFFF, FM_INTR_STC_DONE
, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 69[0] = 1 */
612 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
613 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
620 * mt6627_tune - execute tune action,
622 * @buf_size - buffer size
623 * @freq - 760 ~ 1080, 100KHz unit
624 * return package size
626 fm_s32
mt6627_tune(fm_u8
*buf
, fm_s32 buf_size
, fm_u16 freq
, fm_u16 chan_para
)
628 /* #define FM_TUNE_USE_POLL */
631 if (buf_size
< TX_BUF_SIZE
) {
635 if (0 == fm_get_channel_space(freq)) {
639 freq = (freq - 6400) * 2 / 10;
641 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
642 buf
[1] = FM_TUNE_OPCODE
;
645 /* Set desired channel & channel parameter */
646 #ifdef FM_TUNE_USE_POLL
647 pkt_size
+= fm_bop_write(0x6A, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
);
648 pkt_size
+= fm_bop_write(0x6B, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
);
650 /* pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0xFC00, freq, &buf[pkt_size], buf_size - pkt_size);// set 0x65[9:0] = 0x029e, => ((97.5 - 64) * 20) */
651 /* channel para setting, D15~D12, D15: ATJ, D13: HL, D12: FA */
652 /* pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0x0FFF, (chan_para << 12), &buf[pkt_size], buf_size - pkt_size); */
653 /* Enable hardware controlled tuning sequence */
654 pkt_size
+= fm_bop_modify(FM_MAIN_CTRL
, 0xFFF8, TUNE
, &buf
[pkt_size
], buf_size
- pkt_size
); /* set 0x63[0] = 1 */
655 /* Wait for STC_DONE interrupt */
656 #ifdef FM_TUNE_USE_POLL
657 pkt_size
+= fm_bop_rd_until(FM_MAIN_INTR
, FM_INTR_STC_DONE
, FM_INTR_STC_DONE
, &buf
[pkt_size
], buf_size
- pkt_size
); /* Poll 69[0] = b'1 */
658 /* Write 1 clear the STC_DONE interrupt status flag */
659 pkt_size
+= fm_bop_modify(FM_MAIN_INTR
, 0xFFFF, FM_INTR_STC_DONE
, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 69[0] = 1 */
661 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
662 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
669 * mt6627_full_cqi_req - execute request cqi info action,
671 * @buf_size - buffer size
672 * @freq - 7600 ~ 10800, freq array
673 * @cnt - channel count
674 * @type - request type, 1: a single channel; 2: multi channel; 3:multi channel with 100Khz step; 4: multi channel with 50Khz step
676 * return package size
678 fm_s32
mt6627_full_cqi_req(fm_u8
*buf
, fm_s32 buf_size
, fm_u16
*freq
, fm_s32 cnt
, fm_s32 type
)
682 if (buf_size
< TX_BUF_SIZE
) {
686 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
687 buf
[1] = FM_SOFT_MUTE_TUNE_OPCODE
;
692 buf
[pkt_size
] = 0x0001;
694 buf
[pkt_size
] = (fm_u8
) ((*freq
) & 0x00FF);
696 buf
[pkt_size
] = (fm_u8
) ((*freq
>> 8) & 0x00FF);
700 buf
[pkt_size
] = 0x0002;
704 buf
[pkt_size
] = 0x0003;
708 buf
[pkt_size
] = 0x0004;
712 buf
[pkt_size
] = (fm_u16
) type
;
717 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
718 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
725 * mt6627_seek - execute seek action,
727 * @buf_size - buffer size
728 * @seekdir - 0=seek up, 1=seek down
729 * @space - step, 50KHz:001, 100KHz:010, 200KHz:100
730 * @max_freq - upper bound
731 * @min_freq - lower bound
732 * return package size
734 fm_s32
mt6627_seek(fm_u8
*buf
, fm_s32 buf_size
, fm_u16 seekdir
, fm_u16 space
, fm_u16 max_freq
,
739 if (buf_size
< TX_BUF_SIZE
) {
743 if (0 == fm_get_channel_space(max_freq
)) {
747 if (0 == fm_get_channel_space(min_freq
)) {
751 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
752 buf
[1] = FM_SEEK_OPCODE
;
755 /* Program seek direction */
757 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0xFBFF, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* 0x66[10] = 0, seek up */
759 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0xFBFF, 0x0400, &buf
[pkt_size
], buf_size
- pkt_size
); /* 0x66[10] = 1, seek down */
762 /* Program scan channel spacing */
764 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0x8FFF, 0x1000, &buf
[pkt_size
], buf_size
- pkt_size
); /* clear 0x66[14:12] then 0x66[14:12]=001 */
765 } else if (space
== 2) {
766 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0x8FFF, 0x2000, &buf
[pkt_size
], buf_size
- pkt_size
); /* clear 0x66[14:12] then 0x66[14:12]=010 */
767 } else if (space
== 4) {
768 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0x8FFF, 0x4000, &buf
[pkt_size
], buf_size
- pkt_size
); /* clear 0x66[14:12] then 0x66[14:12]=100 */
770 /* enable wrap , if it is not auto scan function, 0x66[11] 0=no wrarp, 1=wrap */
771 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0xF7FF, 0x0800, &buf
[pkt_size
], buf_size
- pkt_size
); /* 0x66[11] = 1, wrap */
772 /* 0x66[9:0] freq upper bound */
774 max_freq
= (max_freq
- 6400) * 2 / 10;
777 fm_bop_modify(FM_MAIN_CFG1
, 0xFC00, max_freq
, &buf
[pkt_size
], buf_size
- pkt_size
);
778 /* 0x67[9:0] freq lower bound */
780 min_freq
= (min_freq
- 6400) * 2 / 10;
783 fm_bop_modify(FM_MAIN_CFG2
, 0xFC00, min_freq
, &buf
[pkt_size
], buf_size
- pkt_size
);
784 /* Enable hardware controlled seeking sequence */
785 pkt_size
+= fm_bop_modify(FM_MAIN_CTRL
, 0xFFF8, SEEK
, &buf
[pkt_size
], buf_size
- pkt_size
); /* 0x63[1] = 1 */
786 /* Wait for STC_DONE interrupt */
787 /* pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//Poll 69[0] = b'1 */
788 /* Write 1 clear the STC_DONE interrupt status flag */
789 /* pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//wr 69[0] = 1 */
791 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
792 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
799 * mt6627_scan - execute scan action,
801 * @buf_size - buffer size
802 * @scandir - 0=seek up, 1=seek down
803 * @space - step, 50KHz:001, 100KHz:010, 200KHz:100
804 * @max_freq - upper bound
805 * @min_freq - lower bound
806 * return package size
808 fm_s32
mt6627_scan(fm_u8
*buf
, fm_s32 buf_size
, fm_u16 scandir
, fm_u16 space
, fm_u16 max_freq
,
813 if (buf_size
< TX_BUF_SIZE
) {
817 if (0 == fm_get_channel_space(max_freq
)) {
820 if (0 == fm_get_channel_space(min_freq
)) {
824 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
825 buf
[1] = FM_SCAN_OPCODE
;
828 /* Program seek direction */
830 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0xFBFF, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* 0x66[10] = 0, seek up */
832 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0xFFFF, 0x0400, &buf
[pkt_size
], buf_size
- pkt_size
); /* 0x66[10] = 1, seek down */
835 /* Program scan channel spacing */
837 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0x8FFF, 0x1000, &buf
[pkt_size
], buf_size
- pkt_size
); /* clear 0x66[14:12] then 0x66[14:12]=001 */
838 } else if (space
== 2) {
839 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0x8FFF, 0x2000, &buf
[pkt_size
], buf_size
- pkt_size
); /* clear 0x66[14:12] then 0x66[14:12]=010 */
840 } else if (space
== 4) {
841 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0x8FFF, 0x4000, &buf
[pkt_size
], buf_size
- pkt_size
); /* clear 0x66[14:12] then 0x66[14:12]=100 */
843 /* disable wrap , if it is auto scan function, 0x66[11] 0=no wrarp, 1=wrap */
844 pkt_size
+= fm_bop_modify(FM_MAIN_CFG1
, 0xF7FF, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* 0x66[11] = 0, no wrap */
845 /* 0x66[9:0] freq upper bound */
847 max_freq
= (max_freq
- 6400) * 2 / 10;
850 fm_bop_modify(FM_MAIN_CFG1
, 0xFC00, max_freq
, &buf
[pkt_size
], buf_size
- pkt_size
);
851 /* 0x67[9:0] freq lower bound */
853 min_freq
= (min_freq
- 6400) * 2 / 10;
856 fm_bop_modify(FM_MAIN_CFG2
, 0xFC00, min_freq
, &buf
[pkt_size
], buf_size
- pkt_size
);
857 /* Enable hardware controlled scanning sequence */
858 pkt_size
+= fm_bop_modify(FM_MAIN_CTRL
, 0xFFF8, SCAN
, &buf
[pkt_size
], buf_size
- pkt_size
); /* 0x63[1] = 1 */
859 /* Wait for STC_DONE interrupt */
860 /* pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//Poll 69[0] = b'1 */
861 /* Write 1 clear the STC_DONE interrupt status flag */
862 /* pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//wr 69[0] = 1 */
864 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
865 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
871 fm_s32
mt6627_cqi_get(fm_u8
*buf
, fm_s32 buf_size
)
875 if (buf_size
< TX_BUF_SIZE
) {
879 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
880 buf
[1] = FM_SCAN_OPCODE
;
883 pkt_size
+= fm_bop_modify(FM_MAIN_CTRL
, 0xFFF0, 0x0000, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 63 bit0~2 0 */
884 pkt_size
+= fm_bop_modify(FM_MAIN_CTRL
, ~CQI_READ
, CQI_READ
, &buf
[pkt_size
], buf_size
- pkt_size
); /* wr 63 bit3 1 */
886 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
887 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
893 fm_s32
mt6627_get_reg(fm_u8
*buf
, fm_s32 buf_size
, fm_u8 addr
)
895 if (buf_size
< TX_BUF_SIZE
) {
899 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
900 buf
[1] = FSPI_READ_OPCODE
;
905 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2], buf
[3],
911 fm_s32
mt6627_set_reg(fm_u8
*buf
, fm_s32 buf_size
, fm_u8 addr
, fm_u16 value
)
913 if (buf_size
< TX_BUF_SIZE
) {
917 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
918 buf
[1] = FSPI_WRITE_OPCODE
;
922 buf
[5] = (fm_u8
) ((value
) & 0x00FF);
923 buf
[6] = (fm_u8
) ((value
>> 8) & 0x00FF);
925 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2],
926 buf
[3], buf
[4], buf
[5], buf
[6]);
931 fm_s32
mt6627_set_bits_reg(fm_u8
*buf
, fm_s32 buf_size
, fm_u8 addr
, fm_u16 bits
, fm_u16 mask
)
934 if (buf_size
< TX_BUF_SIZE
) {
938 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
939 buf
[1] = 0x11; /* 0x11 this opcode won't be parsed as an opcode, so set here as spcial case. */
941 pkt_size
+= fm_bop_modify(addr
, mask
, bits
, &buf
[pkt_size
], buf_size
- pkt_size
);
943 buf
[2] = (fm_u8
) ((pkt_size
- 4) & 0x00FF);
944 buf
[3] = (fm_u8
) (((pkt_size
- 4) >> 8) & 0x00FF);
949 /*top register read*/
950 fm_s32
mt6627_top_get_reg(fm_u8
*buf
, fm_s32 buf_size
, fm_u16 addr
)
952 if (buf_size
< TX_BUF_SIZE
) {
956 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
957 buf
[1] = CSPI_READ_OPCODE
;
960 buf
[4] = 0x04; /* top 04,fm 02 */
961 buf
[5] = (fm_u8
) ((addr
) & 0x00FF);
962 buf
[6] = (fm_u8
) ((addr
>> 8) & 0x00FF);
964 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2],
965 buf
[3], buf
[4], buf
[5], buf
[6]);
970 fm_s32
mt6627_top_set_reg(fm_u8
*buf
, fm_s32 buf_size
, fm_u16 addr
, fm_u32 value
)
972 if (buf_size
< TX_BUF_SIZE
) {
976 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
977 buf
[1] = CSPI_WRITE_OPCODE
;
980 buf
[4] = 0x04; /* top 04,fm 02 */
981 buf
[5] = (fm_u8
) ((addr
) & 0x00FF);
982 buf
[6] = (fm_u8
) ((addr
>> 8) & 0x00FF);
983 buf
[7] = (fm_u8
) ((value
) & 0x00FF);
984 buf
[8] = (fm_u8
) ((value
>> 8) & 0x00FF);
985 buf
[9] = (fm_u8
) ((value
>> 16) & 0x00FF);
986 buf
[10] = (fm_u8
) ((value
>> 24) & 0x00FF);
988 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", buf
[0],
989 buf
[1], buf
[2], buf
[3], buf
[4], buf
[5], buf
[6], buf
[7], buf
[8], buf
[9], buf
[10]);
993 /*host register read*/
994 fm_s32
mt6627_host_get_reg(fm_u8
*buf
, fm_s32 buf_size
, fm_u32 addr
)
996 if (buf_size
< TX_BUF_SIZE
) {
1000 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
1001 buf
[1] = FM_HOST_READ_OPCODE
;
1004 buf
[4] = (fm_u8
) ((addr
) & 0x00FF);
1005 buf
[5] = (fm_u8
) ((addr
>> 8) & 0x00FF);
1006 buf
[6] = (fm_u8
) ((addr
>> 16) & 0x00FF);
1007 buf
[7] = (fm_u8
) ((addr
>> 24) & 0x00FF);
1009 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x %02x\n", buf
[0], buf
[1], buf
[2],
1010 buf
[3], buf
[4], buf
[5], buf
[6], buf
[7]);
1015 fm_s32
mt6627_host_set_reg(fm_u8
*buf
, fm_s32 buf_size
, fm_u32 addr
, fm_u32 value
)
1017 if (buf_size
< TX_BUF_SIZE
) {
1021 buf
[0] = FM_TASK_COMMAND_PKT_TYPE
;
1022 buf
[1] = FM_HOST_WRITE_OPCODE
;
1025 buf
[4] = (fm_u8
) ((addr
) & 0x00FF);
1026 buf
[5] = (fm_u8
) ((addr
>> 8) & 0x00FF);
1027 buf
[6] = (fm_u8
) ((addr
>> 16) & 0x00FF);
1028 buf
[7] = (fm_u8
) ((addr
>> 24) & 0x00FF);
1029 buf
[8] = (fm_u8
) ((value
) & 0x00FF);
1030 buf
[9] = (fm_u8
) ((value
>> 8) & 0x00FF);
1031 buf
[10] = (fm_u8
) ((value
>> 16) & 0x00FF);
1032 buf
[11] = (fm_u8
) ((value
>> 24) & 0x00FF);
1034 WCN_DBG(FM_DBG
| CHIP
, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
1035 buf
[0], buf
[1], buf
[2], buf
[3], buf
[4], buf
[5], buf
[6], buf
[7], buf
[8], buf
[9],