1 #include <linux/semaphore.h>
2 #include <linux/delay.h>
3 #include <linux/slab.h>
8 #include "fm_typedef.h"
11 #include "fm_interface.h"
12 #include "fm_stdlib.h"
16 #include "fm_config.h"
17 #include "fm_private.h"
19 #include "mt6620_fm_reg.h"
20 #include "mt6620_fm.h"
21 //#include "mt6620_drv_dsp.h"
22 //#include "mt6620_fm_link.h"
23 #include "mt6620_fm_lib.h"
24 #include "mt6620_fm_cmd.h"
25 #include "mt6620_fm_cust_cfg.h"
26 #ifdef MTK_FM_50KHZ_SUPPORT
27 static struct fm_fifo *cqi_fifo = NULL;
29 extern fm_cust_cfg mt6620_fm_config;
30 static struct fm_hw_info mt6620_hw_info = {
31 .chip_id = 0x00006620,
32 .eco_ver = 0x00000000,
33 .rom_ver = 0x00000002,
34 .patch_ver = 0x00000111,
35 .reserve = 0x00000000,
37 static struct fm_i2s_info mt6620_i2s_inf = {
38 .status = 0, //i2s off
39 .mode = 0, //slave mode
40 .rate = 48000, //48000 sample rate
43 fm_s32 MT6620_HL_Side_Adj(fm_u16 freq, fm_s32 *hl);
44 fm_s32 MT6620_ADPLL_Freq_Avoid(fm_u16 freq, fm_s32 *freqavoid);
45 fm_s32 MT6620_MCU_Freq_Avoid(fm_u16 freq, fm_s32 *freqavoid);
46 fm_s32 MT6620_ADPLL_Power_OnOff(fm_s32 onoff, fm_s32 ADPLL_clk);
47 fm_s32 MT6620_TX_PWR_CTRL(fm_u16 freq, fm_s32 *ctr);
48 fm_s32 MT6620_RTC_Drift_CTRL(fm_u16 freq, fm_s32 *ctr);
49 fm_s32 MT6620_TX_DESENSE(fm_u16 freq, fm_s32 *ctr);
51 static fm_s32 mt6620_I2s_Setting(fm_s32 onoff, fm_s32 mode, fm_s32 sample);
52 static fm_s32 mt6620_desense_check(fm_u16 freq,fm_s32 rssi);
53 static fm_s32 MT6620_Rds_Tx(fm_u16 pi, fm_u16 *ps, fm_u16 *other_rds, fm_u8 other_rds_cnt);
54 static fm_s32 MT6620_Rds_Tx_Enable(void);
55 static fm_s32 MT6620_Rds_Tx_Disable(void);
57 static fm_u8 *cmd_buf = NULL;
58 static struct fm_lock *cmd_buf_lock = NULL;
59 static struct fm_callback *fm_cb_op;
60 //static struct MT6620fm_priv priv_adv_6620;
61 static ENUM_WMTHWVER_TYPE_T hw_ver=WMTHWVER_MT6620_E3;
62 static fm_s32 mt6620_pwron(fm_s32 data)
64 if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM)) {
65 WCN_DBG(FM_ALT | CHIP, "WMT turn on FM Fail!\n");
68 /* GeorgeKuo: turn on function before check stp ready */
69 if(fm_false == mtk_wcn_stp_is_ready())
71 WCN_DBG(FM_ALT | MAIN,"6620 stp is not ready, please retry later\n");
74 hw_ver = mtk_wcn_wmt_hwver_get();
75 WCN_DBG(FM_ALT | CHIP, "WMT turn on FM OK!\n");
81 static fm_s32 mt6620_pwroff(fm_s32 data)
83 if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM)) {
84 WCN_DBG(FM_ALT | CHIP, "WMT turn off FM Fail!\n");
87 WCN_DBG(FM_NTC | CHIP, "WMT turn off FM OK!\n");
92 static fm_s32 Delayms(fm_u32 data)
94 WCN_DBG(FM_DBG | CHIP, "delay %dms\n", data);
99 static fm_s32 Delayus(fm_u32 data)
101 WCN_DBG(FM_DBG | CHIP, "delay %dus\n", data);
106 static struct fm_res_ctx *res = NULL;
108 fm_s32 mt6620_get_read_result(struct fm_res_ctx* result)
116 static fm_s32 mt6620_read(fm_u8 addr, fm_u16 *val)
121 if (FM_LOCK(cmd_buf_lock))
123 pkt_size = mt6620_get_reg(cmd_buf, TX_BUF_SIZE, addr);
124 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_FSPI_RD, SW_RETRY_CNT, FSPI_RD_TIMEOUT, mt6620_get_read_result);
130 FM_UNLOCK(cmd_buf_lock);
135 static fm_s32 mt6620_write(fm_u8 addr, fm_u16 val)
140 if (FM_LOCK(cmd_buf_lock))
142 pkt_size = mt6620_set_reg(cmd_buf, TX_BUF_SIZE, addr, val);
143 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_FSPI_WR, SW_RETRY_CNT, FSPI_WR_TIMEOUT, NULL);
144 FM_UNLOCK(cmd_buf_lock);
149 static fm_s32 mt6620_set_bits(fm_u8 addr, fm_u16 bits, fm_u16 mask)
154 ret = mt6620_read(addr, &val);
159 val = ((val & (mask)) | bits);
160 ret = mt6620_write(addr, val);
165 static fm_u16 mt6620_get_chipid(void)
170 /* mt6620_SetAntennaType - set Antenna type
171 * @type - 1,Short Antenna; 0, Long Antenna
173 static fm_s32 mt6620_SetAntennaType(fm_s32 type)
175 WCN_DBG(FM_DBG | CHIP, "set ana to %s\n", type ? "short" : "long");
177 if (type == FM_ANA_LONG) {
178 //Long Antenna RSSI threshold, 0xE0 D0~D9
179 mt6620_write(0xE0, ((0xA301 & 0xFC00) | (FMR_RSSI_TH_LONG_MT6620 & 0x03FF)));
180 //Turn on Short Antenna LNA and Off TR Switch
181 mt6620_write(0x04, 0x0142);
182 //Turn off the Short Antenna Capbank biasing
183 mt6620_write(0x05, 0x00E7);
184 //Turn off the Short Antenna Capbank biasing
185 mt6620_write(0x26, 0x0004);
186 //Disable concurrent calibration for VCO and SCAL
187 mt6620_write(0x2E, 0x0008);
188 } else if (type == FM_ANA_SHORT) {
189 //Short Antenna RSSI threshold, 0xE0 D0~D9
190 mt6620_write(0xE0, ((0xA2E0 & 0xFC00) | (FMR_RSSI_TH_SHORT_MT6620 & 0x03FF)));
191 //Turn on Short Antenna LNA and TR Switch
192 mt6620_write(0x04, 0x0145);
193 //Turn on the Short Antenna Capbank biasing
194 mt6620_write(0x05, 0x00FF);
195 //Turn on the Short Antenna Capbank biasing
196 mt6620_write(0x26, 0x0024);
197 //Enable concurrent calibration for VCO and SCAL
198 mt6620_write(0x2E, 0x0000);
200 WCN_DBG(FM_ERR | CHIP, "%s()\n", __func__);
207 static fm_s32 mt6620_GetAntennaType(void)
211 mt6620_read(0x2E, &dataRead);
213 if (dataRead == 0x0000)
214 return FM_ANA_SHORT; //short antenna
216 return FM_ANA_LONG; //long antenna
219 static fm_s32 mt6620_Mute(fm_bool mute)
221 WCN_DBG(FM_DBG | CHIP, "set %s\n", mute ? "mute" : "unmute");
224 return mt6620_set_bits(0x9C, 0x0008, 0xFFF7); //1:9C D3 = 1
226 return mt6620_set_bits(0x9c, 0x0000, 0xFFF7); //1:9C D3 = 0
230 static fm_s32 mt6620_RampDown(void)
235 WCN_DBG(FM_NTC | CHIP, "ramp down\n");
237 if (FM_LOCK(cmd_buf_lock))
239 pkt_size = mt6620_rampdown(cmd_buf, TX_BUF_SIZE);
240 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT, NULL);
241 FM_UNLOCK(cmd_buf_lock);
244 WCN_DBG(FM_ERR | CHIP, "ramp down failed\n");
249 #if 0//ramp down tx will do in tx tune flow
250 static fm_s32 MT6620_RampDown_Tx(void)
255 WCN_DBG(FM_NTC | CHIP, "ramp down TX\n");
256 if (FM_LOCK(cmd_buf_lock))
259 pkt_size = mt6620_rampdown_tx(cmd_buf, TX_BUF_SIZE);
260 ret = fm_cmd_tx(cmd_buf, pkt_size,FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT,NULL);
262 FM_UNLOCK(cmd_buf_lock);
264 WCN_DBG(FM_ERR | CHIP, "ramp down TX failed\n");
269 static fm_s32 mt6620_PowerUp(fm_u16 *chip_id, fm_u16 *device_id)
275 FMR_ASSERT(device_id);
277 WCN_DBG(FM_DBG | CHIP, "pwr on seq......\n");
279 //Wholechip FM Power Up: step 1, mt6620_off_2_longANA
280 if (FM_LOCK(cmd_buf_lock))
282 pkt_size = mt6620_off_2_longANA_1(cmd_buf, TX_BUF_SIZE);
283 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL);
284 FM_UNLOCK(cmd_buf_lock);
287 WCN_DBG(FM_ALT | CHIP, "mt6620_off_2_longANA_1 failed\n");
293 if (FM_LOCK(cmd_buf_lock))
295 pkt_size = mt6620_off_2_longANA_2(cmd_buf, TX_BUF_SIZE);
296 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL);
297 FM_UNLOCK(cmd_buf_lock);
300 WCN_DBG(FM_ALT | CHIP, "mt6620_off_2_longANA_2 failed\n");
306 // *chip_id = 0x6620;
307 // *device_id = 0x6620;
308 // WCN_DBG(FM_NTC | CHIP, "chip_id:0x%04x\n", 0x6620);
310 //Wholechip FM Power Up: step 2, FM Digital Init: fm_rgf_maincon
311 if (FM_LOCK(cmd_buf_lock))
313 pkt_size = mt6620_pwrup_digital_init_1(cmd_buf, TX_BUF_SIZE);
314 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL);
315 FM_UNLOCK(cmd_buf_lock);
318 WCN_DBG(FM_ALT | CHIP, "mt6620_pwrup_digital_init_2 failed\n");
324 if (FM_LOCK(cmd_buf_lock))
326 pkt_size = mt6620_pwrup_digital_init_2(cmd_buf, TX_BUF_SIZE);
327 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL);
328 FM_UNLOCK(cmd_buf_lock);
331 WCN_DBG(FM_ALT | CHIP, "mt6620_pwrup_digital_init_2 failed\n");
337 if (FM_LOCK(cmd_buf_lock))
339 pkt_size = mt6620_pwrup_digital_init_3(cmd_buf, TX_BUF_SIZE);
340 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL);
341 FM_UNLOCK(cmd_buf_lock);
344 WCN_DBG(FM_ALT | CHIP, "mt6620_pwrup_digital_init_3 failed\n");
347 #ifdef FM_DIGITAL_INPUT
348 #ifdef MT6573 //for MT6573
349 if(get_chip_eco_ver() == CHIP_E1){
350 ret = mt6620_I2s_Setting(MT6620_I2S_ON, MT6620_I2S_MASTER, MT6620_I2S_48K);
352 ret = mt6620_I2s_Setting(MT6620_I2S_ON, MT6620_I2S_SLAVE, MT6620_I2S_48K);
355 ret = mt6620_I2s_Setting(MT6620_I2S_ON, MT6620_I2S_SLAVE, MT6620_I2S_48K);
358 WCN_DBG(FM_ERR |CHIP,"pwron set I2S on error\n");
361 //we will disable 6620 fm chip analog output when use I2S path, set 0x3A bit2 = 0
362 //mt6620_set_bits(0x3A, 0, MASK(2));
363 WCN_DBG(FM_NTC |CHIP,"pwron set I2S on ok\n");
366 mt6620_hw_info.eco_ver = (fm_s32)mtk_wcn_wmt_hwver_get();
367 WCN_DBG(FM_DBG | CHIP, "pwr on seq ok\n");
370 static fm_s32 mt6620_PowerUpTx(void)
376 WCN_DBG(FM_DBG | CHIP, "pwr on Tx seq......\n");
378 if (FM_LOCK(cmd_buf_lock))
380 pkt_size = mt6620_off_2_tx_shortANA(cmd_buf, TX_BUF_SIZE);
381 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL);
382 FM_UNLOCK(cmd_buf_lock);
385 WCN_DBG(FM_ALT | CHIP, "mt6620_off_2_tx_shortANA failed\n");
390 mt6620_read(0x62, &dataRead);
391 WCN_DBG(FM_NTC | CHIP, "Tx on chipid=%x\n",dataRead);
393 if (FM_LOCK(cmd_buf_lock))
395 pkt_size = mt6620_dig_init(cmd_buf, TX_BUF_SIZE);
396 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL);
397 FM_UNLOCK(cmd_buf_lock);
400 WCN_DBG(FM_ALT | CHIP, "mt6620_dig_init failed\n");
404 if(mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE) != fm_true)
406 WCN_DBG(FM_ERR | MAIN, "wmt_therm_ctrl, WMTTHERM_ENABLE failed\n");
410 #ifdef FM_DIGITAL_INPUT
411 ret = mt6620_I2s_Setting(MT6620_I2S_ON, MT6620_I2S_SLAVE, MT6620_I2S_48K);
413 WCN_DBG(FM_ERR |CHIP,"pwron tx set I2S on error\n");
416 //we will disable 6620 fm chip analog output when use I2S path, set 0x3A bit2 = 0
417 //mt6620_set_bits(0x3A, 0, MASK(2));
418 WCN_DBG(FM_NTC |CHIP,"pwron set I2S on ok\n");
421 WCN_DBG(FM_DBG | CHIP, "pwr on tx seq ok\n");
425 static fm_s32 mt6620_PowerDown(void)
430 WCN_DBG(FM_DBG | CHIP, "pwr down seq\n");
432 // mt6620_RampDown();
434 if (FM_LOCK(cmd_buf_lock))
436 pkt_size = mt6620_pwrdown(cmd_buf, TX_BUF_SIZE);
437 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT, NULL);
438 FM_UNLOCK(cmd_buf_lock);
441 WCN_DBG(FM_ALT | CHIP, "mt6620_pwrdown failed\n");
448 static fm_s32 mt6620_PowerDownTx(void)
452 if(mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE) != fm_true)
454 WCN_DBG(FM_ERR | MAIN, "wmt_therm_ctrl, WMTTHERM_DISABLE failed\n");
461 static fm_bool MT6620_SetFreq_Tx(fm_u16 freq)
466 fm_cb_op->cur_freq_set(freq);
468 if (FM_LOCK(cmd_buf_lock))
470 pkt_size = mt6620_tune_tx(cmd_buf, TX_BUF_SIZE, freq);
471 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL);
472 FM_UNLOCK(cmd_buf_lock);
475 WCN_DBG(FM_ALT | CHIP, "mt6620_tune_tx failed\n");
481 WCN_DBG(FM_DBG | CHIP, "mt6620_tune_tx to %d ok\n", freq);
487 * fm_print_curCQI -- print cur freq's CQI
488 * @cur_freq, current frequency
489 * If OK, return 0, else error code
491 static fm_s32 mt6620_print_curCQI(fm_u16 cur_freq)
498 if((ret = mt6620_write(FM_MAIN_PGSEL, FM_PG0)))
500 if((ret = mt6620_read(FM_RSSI_IND, &rssi)))
502 if((ret = mt6620_read(FM_ADDR_PAMD, &pamd)))
504 if((ret = mt6620_read(FM_MR_IND, &mr)))
507 WCN_DBG(FM_NTC |CHIP,"FREQ=%d, RSSI=0x%04x, PAMD=0x%04x, MR=0x%04x\n", (fm_s32)cur_freq, rssi, pamd, mr);
511 static fm_bool mt6620_SetFreq(fm_u16 freq)
515 fm_s32 freq_avoid = -1;
518 fm_cb_op->cur_freq_set(freq);
520 if((ret = MT6620_HL_Side_Adj(freq, &hl_side)))
522 WCN_DBG(FM_NTC |CHIP,"%s, [hl_side=%d]\n", __func__, hl_side);
524 if((ret = MT6620_ADPLL_Freq_Avoid(freq, &freq_avoid)))
526 WCN_DBG(FM_NTC |CHIP,"%s, adpll [freq_avoid=%d]\n", __func__, freq_avoid);
528 // hw_ver = mtk_wcn_wmt_hwver_get();
529 if(hw_ver >= WMTHWVER_MT6620_E3)
531 if((ret = MT6620_MCU_Freq_Avoid(freq, &freq_avoid)))
533 WCN_DBG(FM_NTC |CHIP,"%s, mcu [freq_avoid=%d]\n", __func__, freq_avoid);
537 WCN_DBG(FM_NTC |CHIP,"%s, no need do mcu freq avoid[hw_ver=%d]\n", __func__, hw_ver);
541 if (FM_LOCK(cmd_buf_lock))
543 pkt_size = mt6620_tune_1(cmd_buf, TX_BUF_SIZE, freq);
544 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL);
545 FM_UNLOCK(cmd_buf_lock);
548 WCN_DBG(FM_ALT | CHIP, "mt6620_tune_1 failed\n");
554 if (FM_LOCK(cmd_buf_lock))
556 pkt_size = mt6620_tune_2(cmd_buf, TX_BUF_SIZE, freq);
557 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL);
558 FM_UNLOCK(cmd_buf_lock);
561 WCN_DBG(FM_ALT | CHIP, "mt6620_tune_2 failed\n");
567 if (FM_LOCK(cmd_buf_lock))
569 pkt_size = mt6620_tune_3(cmd_buf, TX_BUF_SIZE, freq);
570 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL);
571 FM_UNLOCK(cmd_buf_lock);
574 WCN_DBG(FM_ALT | CHIP, "mt6620_tune_3 failed\n");
578 ret = mt6620_print_curCQI(freq);
579 WCN_DBG(FM_DBG | CHIP, "set freq to %d ok\n", freq);
585 static fm_s32 mt6620_TxScan_SetFreq(fm_u16 freq)
590 WCN_DBG(FM_NTC | CHIP,"+%s():[freq=%d]\n", __func__, freq);
591 if (FM_LOCK(cmd_buf_lock))
594 pkt_size = mt6620_tune_txscan(cmd_buf, TX_BUF_SIZE, freq);
595 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT, NULL);
596 FM_UNLOCK(cmd_buf_lock);
598 FM_UNLOCK(cmd_buf_lock);
599 WCN_DBG(FM_NTC | CHIP,"-%s():[ret=%d]\n", __func__, ret);
603 static fm_s32 mt6620_TxScan_GetCQI(fm_s16 *pRSSI, fm_s16 *pPAMD, fm_s16 *pMR)
612 WCN_DBG(FM_NTC | CHIP,"+%s():\n", __func__);
614 if((pRSSI == NULL) || (pPAMD == NULL) || (pMR == NULL)){
615 WCN_DBG(FM_ERR | CHIP,"%s():para error, [pRSSI=%p],[aPAMD=%p],[pMR=%p]\n",
616 __func__, pRSSI, pPAMD, pMR);
621 for(cnt = 0; cnt < 8; cnt++)
624 if((ret = mt6620_read(FM_RSSI_IND, &tmp_reg)))
626 tmp_reg = tmp_reg&0x03ff;
627 tmp_reg = (tmp_reg > 511) ? ((fm_s16)(tmp_reg-1024)) : tmp_reg;
630 if((ret = mt6620_read(FM_ADDR_PAMD, &tmp_reg)))
632 tmp_reg = tmp_reg&0x00ff;
633 tmp_reg = (tmp_reg > 127) ? ((fm_s16)(tmp_reg-256)) : tmp_reg;
636 if((ret = mt6620_read(FM_MR_IND, &tmp_reg)))
638 tmp_reg = tmp_reg&0x01ff;
639 tmp_reg = (tmp_reg > 255) ? ((fm_s16)(tmp_reg-512)) : tmp_reg;
647 WCN_DBG(FM_NTC | CHIP,"%s():[RSSI=%d],[PAMD=%d],[MR=%d]\n",
648 __func__, *pRSSI, *pPAMD, *pMR);
651 WCN_DBG(FM_NTC | CHIP,"-%s():[ret=%d]\n", __func__, ret);
655 static fm_s32 mt6620_TxScan_IsEmptyChannel(fm_s16 RSSI, fm_s16 PAMD, fm_s16 MR, fm_s32 *empty)
659 WCN_DBG(FM_NTC | CHIP,"+%s():[RSSI=%d],[PAMD=%d],[MR=%d]\n", __func__, RSSI, PAMD, MR);
663 WCN_DBG(FM_NTC | CHIP,"invalid pointer [empty=0x%x]!\n", (fm_u32)empty);
669 if(RSSI > FM_TXSCAN_RSSI_TH){
674 if(PAMD < FM_TXSCAN_PAMD_TH){
679 if(MR < FM_TXSCAN_MR_TH){
685 WCN_DBG(FM_NTC | CHIP,"-%s():[ret=%d]\n", __func__, ret);
689 static fm_s32 mt6620_TxScan(fm_u16 min_freq,
698 fm_u16 freq = *pFreq;
699 fm_u16 scan_cnt = *ScanTBLsize;
708 WCN_DBG(FM_NTC | CHIP,"+%s():\n", __func__);
710 if((!pScanTBL) || (*ScanTBLsize < FM_TX_SCAN_MIN) || (*ScanTBLsize > FM_TX_SCAN_MAX))
712 WCN_DBG(FM_ERR | CHIP,"+%s():invalid scan table\n", __func__);
717 WCN_DBG(FM_NTC | CHIP, "[freq=%d], [max_freq=%d],[min_freq=%d],[scan BTL size=%d],[scandir=%d],[space=%d]\n",
718 *pFreq, max_freq, min_freq, *ScanTBLsize, scandir, space);
721 /* if (space == MT6620_FM_SPACE_100K) {
723 } else if (space == MT6620_FM_SPACE_50K) {
725 } else if (space == MT6620_FM_SPACE_200K) {
732 while(!(!(cnt < scan_cnt) || (freq > max_freq) || (freq < min_freq))){
734 //Set desired channel, tune to the channel, and perform fast AGC
735 counter++; //just for debug
737 ret = mt6620_TxScan_SetFreq(freq);
739 WCN_DBG(FM_ERR | CHIP,"%s():set freq failed\n", __func__);
743 //wait 8~10ms for RF setting
745 //wait 4 AAGC period for AAGC setting, AAGC period = 1024/480k = 2.13ms
748 ret = mt6620_TxScan_GetCQI(&rssi, &pamd, &mr);
750 WCN_DBG(FM_ERR | CHIP,"%s():get CQI failed\n", __func__);
754 ret = mt6620_TxScan_IsEmptyChannel(rssi, pamd, mr, &empty);
756 if((empty == fm_true) && ((freq < FM_TX_SCAN_HOLE_LOW) || (freq > FM_TX_SCAN_HOLE_HIGH))){
757 *(pScanTBL + cnt) = freq; //strore the valid empty channel
759 WCN_DBG(FM_NTC | CHIP,"empty channel:[freq=%d] [cnt=%d]\n", freq, cnt);
762 WCN_DBG(FM_ERR | CHIP,"%s():IsEmptyChannel failed\n", __func__);
766 if(scandir == FM_TX_SCAN_UP){
767 if(freq == FM_TX_SCAN_HOLE_LOW){
768 freq += (FM_TX_SCAN_HOLE_HIGH - FM_TX_SCAN_HOLE_LOW + step);
772 }else if(scandir == FM_TX_SCAN_DOWN){
773 if(freq == FM_TX_SCAN_HOLE_HIGH){
774 freq -= (FM_TX_SCAN_HOLE_HIGH - FM_TX_SCAN_HOLE_LOW + step);
779 WCN_DBG(FM_ERR | CHIP,"%s():scandir para error\n", __func__);
786 *pFreq = *(pScanTBL + cnt);
787 WCN_DBG(FM_NTC | CHIP, "completed, [cnt=%d],[freq=%d],[counter=%d]\n", cnt, freq, counter);
790 WCN_DBG(FM_NTC | CHIP,"-%s():[ret=%d]\n", __func__, ret);
796 * @pFreq - IN/OUT parm, IN start freq/OUT seek valid freq
797 * @seekdir - 0:up, 1:down
798 * @space - 1:50KHz, 2:100KHz, 4:200KHz
799 * return fm_true:seek success; fm_false:seek failed
801 static fm_bool mt6620_Seek(fm_u16 min_freq, fm_u16 max_freq, fm_u16 *pFreq, fm_u16 seekdir, fm_u16 space)
804 fm_u16 pkt_size,temp;
807 mt6620_read(0x9C, &temp);
808 mt6620_Mute(fm_true);
810 if (FM_LOCK(cmd_buf_lock))
812 pkt_size = mt6620_seek_1(cmd_buf, TX_BUF_SIZE, seekdir, space, max_freq, min_freq);
813 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SEEK | FLAG_SEEK_DONE, SW_RETRY_CNT, SEEK_TIMEOUT, mt6620_get_read_result);
814 FM_UNLOCK(cmd_buf_lock);
817 *pFreq = res->seek_result;
818 fm_cb_op->cur_freq_set(*pFreq);
820 WCN_DBG(FM_ALT | CHIP, "mt6620_seek_1 failed\n");
826 if (FM_LOCK(cmd_buf_lock))
828 pkt_size = mt6620_seek_2(cmd_buf, TX_BUF_SIZE, seekdir, space, max_freq, min_freq);
829 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SEEK | FLAG_SEEK_DONE, SW_RETRY_CNT, SEEK_TIMEOUT, mt6620_get_read_result);
830 FM_UNLOCK(cmd_buf_lock);
833 WCN_DBG(FM_ALT | CHIP, "mt6620_seek_2 failed\n");
837 //get the result freq
838 WCN_DBG(FM_NTC | CHIP, "seek, result freq:%d\n", *pFreq);
839 if((temp&0x0008) == 0)
841 mt6620_Mute(fm_false);
847 static fm_bool mt6620_Scan(fm_u16 min_freq, fm_u16 max_freq, fm_u16 *pFreq, fm_u16 *pScanTBL,
848 fm_u16 *ScanTBLsize, fm_u16 scandir, fm_u16 space)
851 fm_u16 pkt_size,temp;
853 fm_u16 tmp_scanTBLsize = *ScanTBLsize;
855 if ((!pScanTBL) || (tmp_scanTBLsize == 0)) {
856 WCN_DBG(FM_ALT | CHIP, "scan, failed:invalid scan table\n");
860 WCN_DBG(FM_DBG | CHIP, "start freq: %d, max_freq:%d, min_freq:%d, scan BTL size:%d, scandir:%d, space:%d\n", *pFreq, max_freq, min_freq, *ScanTBLsize, scandir, space);
863 mt6620_read(0x9C, &temp);
864 mt6620_Mute(fm_true);
866 if (FM_LOCK(cmd_buf_lock))
868 pkt_size = mt6620_scan_1(cmd_buf, TX_BUF_SIZE, scandir, space, max_freq, min_freq);
869 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SCAN | FLAG_SCAN_DONE, SW_RETRY_CNT, SCAN_TIMEOUT, mt6620_get_read_result);
870 FM_UNLOCK(cmd_buf_lock);
873 fm_memcpy(pScanTBL, res->scan_result, sizeof(fm_u16)*FM_SCANTBL_SIZE);
874 WCN_DBG(FM_INF | CHIP, "Rx Scan Result:\n");
876 for (offset = 0; offset < tmp_scanTBLsize; offset++) {
877 WCN_DBG(FM_INF | CHIP, "%d: %04x\n", (fm_s32)offset, *(pScanTBL + offset));
880 *ScanTBLsize = tmp_scanTBLsize;
882 WCN_DBG(FM_ALT | CHIP, "mt6620_scan_1 failed\n");
888 if (FM_LOCK(cmd_buf_lock))
890 pkt_size = mt6620_scan_2(cmd_buf, TX_BUF_SIZE, scandir, space, max_freq, min_freq);
891 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SEEK | FLAG_SEEK_DONE, SW_RETRY_CNT, SEEK_TIMEOUT, mt6620_get_read_result);
892 FM_UNLOCK(cmd_buf_lock);
895 WCN_DBG(FM_ALT | CHIP, "mt6620_scan_2 failed\n");
899 if((temp&0x0008) == 0)
901 mt6620_Mute(fm_false);
908 * mt6620_GetCurRSSI - get current freq's RSSI value
910 * If RS>511, then RSSI(dBm)= (RS-1024)/16*6
911 * else RSSI(dBm)= RS/16*6
913 static fm_s32 mt6620_GetCurRSSI(fm_s32 *pRSSI)
917 mt6620_read(FM_RSSI_IND, &tmp_reg);
918 tmp_reg = tmp_reg & 0x03ff;
921 *pRSSI = (tmp_reg > 511) ? (((tmp_reg - 1024) * 6) >> 4) : ((tmp_reg * 6) >> 4);
922 WCN_DBG(FM_DBG | CHIP, "rssi:%d, dBm:%d\n", tmp_reg, *pRSSI);
924 WCN_DBG(FM_ERR | CHIP, "get rssi para error\n");
931 static fm_s32 MT6620_Fast_SetFreq(fm_u16 freq)
936 if (FM_LOCK(cmd_buf_lock))
938 pkt_size = mt6620_fast_tune(cmd_buf, TX_BUF_SIZE, freq);
939 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_TUNE, SW_RETRY_CNT, SEEK_TIMEOUT, mt6620_get_read_result);
940 FM_UNLOCK(cmd_buf_lock);
943 WCN_DBG(FM_ALT | CHIP, "mt6620_fast_tune failed\n");
950 * mt6620_get_RSSI - set freq and return RSSI value
953 static fm_s32 mt6620_GetFreqCQI(fm_u16 freq,fm_s32 *pRSSI)
955 if(MT6620_Fast_SetFreq(freq))
957 mt6620_GetCurRSSI(pRSSI);
963 static fm_u8 mt6620_vol_tbl[16] = {
964 0, 1, 2, 3, 4, 5, 7, 9, 11, 14, 17, 21, 25, 30, 36, 43
966 static fm_s32 mt6620_SetVol(fm_u8 vol)
969 fm_u8 tmp_vol;// = vol & 0x3f;
971 vol = (vol > 15) ? 15 : vol;
972 tmp_vol = mt6620_vol_tbl[vol] & 0x3f;
973 if (tmp_vol > MT6620_VOL_MAX)
974 tmp_vol = MT6620_VOL_MAX;
976 ret = mt6620_set_bits(0x9C, (tmp_vol << 8), 0xC0FF);
979 WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", tmp_vol);
982 WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", tmp_vol);
988 static fm_s32 mt6620_GetVol(fm_u8 *pVol)
995 ret = mt6620_read(0x9C, &tmp_reg);
999 WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n");
1002 *pVol = (tmp_reg >> 8) & 0x3f;
1003 if(*pVol == MT6620_VOL_MAX)
1007 WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol);
1014 static fm_s32 mt6620_dump_reg(void)
1018 for(i=0; i<0xff; i++)
1020 mt6620_read(i, &TmpReg);
1021 WCN_DBG(FM_NTC | CHIP, "0x%02x=0x%04x\n",i,TmpReg);
1027 static fm_bool mt6620_GetMonoStereo(fm_u16 *pMonoStereo)
1031 mt6620_write(FM_MAIN_PGSEL, 0x0001);
1034 mt6620_read(0xF8, &tmp_reg);
1035 *pMonoStereo = (tmp_reg & 0x0400) >> 10;
1037 WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n");
1041 mt6620_write(FM_MAIN_PGSEL, 0x0000);
1043 WCN_DBG(FM_DBG | CHIP, "MonoStero:0x%04x\n", *pMonoStereo);
1048 * MT6620_SetMonoStereo
1049 * Force set to stero/mono mode
1050 * @MonoStereo -- 0, auto; 1, force mono
1051 * If success, return 0; else error code
1053 static fm_s32 MT6620_SetMonoStereo(fm_s32 MonoStereo)
1058 if((ret = mt6620_write(FM_MAIN_PGSEL, FM_PG1)))
1061 tmp_reg = MonoStereo ? BITn(1) : 0; //MonoStereo, 1: force mono; 0:auto
1062 if((ret = mt6620_set_bits(FM_STEROMONO_CTR, tmp_reg, MASK(1))))//set E0 D1=0
1065 if((ret = mt6620_write(FM_MAIN_PGSEL, FM_PG0)))
1068 WCN_DBG(FM_DBG | CHIP,"set to %s\n", MonoStereo ? "auto" : "force mono");
1074 static fm_s32 mt6620_GetCapArray(fm_s32 *ca)
1080 mt6620_read(0x26, &dataRead);
1087 * mt6620_GetCurPamd - get current freq's PAMD value
1089 * If PA>511 then PAMD(dB)= (PA-1024)/16*6,
1090 * else PAMD(dB)=PA/16*6
1092 static fm_bool mt6620_GetCurPamd(fm_u16 *pPamdLevl)
1095 fm_u16 dBvalue=0,valid_cnt=0;
1098 for (i = 0; i < 8; i++)
1100 if (mt6620_read(FM_ADDR_PAMD, &tmp_reg))
1107 dBvalue = (tmp_reg>127) ? ((256-tmp_reg)*6/16):0;
1112 WCN_DBG(FM_DBG | CHIP, "[%d]PAMD=%d\n",i,dBvalue);
1118 *pPamdLevl = total/valid_cnt;
1124 WCN_DBG(FM_DBG | CHIP,"PamdLevl=%d\n", *pPamdLevl);
1128 static fm_s32 mt6620_ScanStop(void)
1130 return fm_force_active_event(FLAG_SCAN);
1133 static fm_s32 mt6620_SeekStop(void)
1135 return fm_force_active_event(FLAG_SEEK);
1139 * mt6620_I2s_Setting - set the I2S state on MT6620
1140 * @onoff - I2S on/off
1141 * @mode - I2S mode: Master or Slave
1143 * Return:0, if success; error code, if failed
1145 static fm_s32 mt6620_I2s_Setting(fm_s32 onoff, fm_s32 mode, fm_s32 sample)
1147 fm_u16 tmp_state = 0;
1148 fm_u16 tmp_mode = 0;
1149 fm_u16 tmp_sample = 0;
1152 if (onoff == MT6620_I2S_ON) {
1153 tmp_state = 0x01; //I2S Frequency tracking on
1154 mt6620_i2s_inf.status = 1;
1155 } else if (onoff == MT6620_I2S_OFF) {
1156 tmp_state = 0x00; //I2S Frequency tracking off
1157 mt6620_i2s_inf.status = 0;
1159 WCN_DBG(FM_ERR | CHIP, "%s():[onoff=%d]\n", __func__, onoff);
1164 if (mode == MT6620_I2S_MASTER) {
1165 tmp_mode = 0x03; //6620 as I2S master
1166 mt6620_i2s_inf.mode = 1;
1167 } else if (mode == MT6620_I2S_SLAVE) {
1168 tmp_mode = 0x0B; //6620 as I2S slave
1169 mt6620_i2s_inf.mode = 0;
1171 WCN_DBG(FM_ERR | CHIP, "%s():[mode=%d]\n", __func__, mode);
1176 if (sample == MT6620_I2S_32K) {
1177 tmp_sample = 0x0000; //6620 I2S 32KHz sample rate
1178 mt6620_i2s_inf.rate = 32000;
1179 } else if (sample == MT6620_I2S_44K) {
1180 tmp_sample = 0x0800; //6620 I2S 44.1KHz sample rate
1181 mt6620_i2s_inf.rate = 44100;
1182 } else if (sample == MT6620_I2S_48K) {
1183 tmp_sample = 0x1000; //6620 I2S 48KHz sample rate
1184 mt6620_i2s_inf.rate = 48000;
1186 WCN_DBG(FM_ERR | CHIP, "%s():[sample=%d]\n", __func__, sample);
1191 if ((ret = mt6620_set_bits(0x5F, tmp_sample, 0xE7FF)))
1194 if ((ret = mt6620_write(0x9B, tmp_mode)))
1197 if ((ret = mt6620_set_bits(0x56, tmp_state, 0xFF7F)))
1200 WCN_DBG(FM_NTC | CHIP, "[onoff=%s][mode=%s][sample=%d](0)33KHz,(1)44.1KHz,(2)48KHz\n",
1201 (onoff == MT6620_I2S_ON) ? "On" : "Off",
1202 (mode == MT6620_I2S_MASTER) ? "Master" : "Slave",
1207 static fm_s32 mt6620_Tx_Support(fm_s32 *sup)
1213 static fm_s32 mt6620_rdsTx_Support(fm_s32 *sup)
1219 static fm_s32 MT6620_FMOverBT(fm_bool enable)
1222 static fm_u16 state = 0;
1223 static fm_u16 mode = 0;
1224 static fm_u16 sample = 0;
1225 static fm_u16 inited = fm_false;
1227 WCN_DBG(FM_NTC | CHIP,"+%s():\n", __func__);
1228 if(inited == fm_false)
1231 if((ret = mt6620_read(0x56, &state)))
1233 if((ret = mt6620_read(0x9B, &mode)))
1235 if((ret = mt6620_read(0x5F, &sample)))
1238 WCN_DBG(FM_NTC | CHIP,"init, record priv seetings\n");
1241 if(enable == fm_true){
1242 //disable analog output when FM over BT
1243 if((ret = mt6620_set_bits(0x3A, 0, MASK(2))))
1246 if((ret = mt6620_write(0x56, 0x0001)))
1248 if((ret = mt6620_write(0x9B, 0x000b)))
1250 if((ret = mt6620_write(0x5F, 0x1175)))
1252 WCN_DBG(FM_NTC | CHIP,"set FM via BT controller\n");
1254 else if(enable == fm_false)
1256 //enable analog output when FM normal mode
1257 if((ret = mt6620_set_bits(0x3A, BITn(2), MASK(2))))
1259 //recover to priv val
1260 if((ret = mt6620_write(0x56, state)))
1262 if((ret = mt6620_write(0x9B, mode)))
1264 if((ret = mt6620_write(0x5F, sample)))
1266 WCN_DBG(FM_NTC | CHIP,"set FM via Host\n");
1270 WCN_DBG(FM_ERR | CHIP,"%s()\n", __func__);
1275 WCN_DBG(FM_NTC | CHIP,"-%s():[ret=%d]\n", __func__, ret);
1279 /*fm soft mute tune function*/
1280 static fm_s32 mt6620_soft_mute_tune(fm_u16 freq,fm_s32 *rssi,fm_bool *valid)
1284 fm_s32 hilo_side = -1;
1285 struct mt6620_fm_softmute_tune_cqi_t *p_cqi;
1286 fm_s32 RSSI=0, PAMD=0,MR=0, ATDC=0;
1288 fm_u16 softmuteGainLvl=0;
1290 /*set hilo side first(f/w won't do this), need to check whether work if set before rampdown*/
1291 if((ret = MT6620_HL_Side_Adj(freq, &hilo_side)))
1294 if (FM_LOCK(cmd_buf_lock)) return (-FM_ELOCK);
1295 pkt_size = mt6620_full_cqi_req(cmd_buf, TX_BUF_SIZE, freq, 1, 1);
1296 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_SM_TUNE, SW_RETRY_CNT, SM_TUNE_TIMEOUT, mt6620_get_read_result);
1297 FM_UNLOCK(cmd_buf_lock);
1301 WCN_DBG(FM_NTC | CHIP, "smt cqi size %d\n", res->cqi[0]);
1302 p_cqi = (struct mt6620_fm_softmute_tune_cqi_t*)&res->cqi[2];
1304 WCN_DBG(FM_NTC | CHIP, "freq %d, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x\n",
1312 RSSI = ((p_cqi->rssi & 0x03FF) >= 512) ? ((p_cqi->rssi & 0x03FF) - 1024) : (p_cqi->rssi & 0x03FF);
1313 PAMD = ((p_cqi->pamd & 0xFF) >= 128) ? ((p_cqi->pamd & 0x0FF) - 256) : (p_cqi->pamd & 0x0FF);
1314 MR = ((p_cqi->mr & 0x01FF) >= 256) ? ((p_cqi->mr & 0x01FF) - 512) : (p_cqi->mr & 0x01FF);
1315 ATDC =((p_cqi->atdc & 0x0FFF) >= 2048) ? ((p_cqi->atdc & 0x0FFF) - 4096) : (p_cqi->atdc & 0x0FFF);
1318 ATDC = (~(ATDC)) - 1;//Get abs value of ATDC
1320 PRX = (p_cqi->prx & 0x00FF);
1321 softmuteGainLvl = p_cqi->smg;
1322 //check if the channel is valid according to each CQIs
1323 if((RSSI >= mt6620_fm_config.rx_cfg.long_ana_rssi_th)
1324 && (PAMD <= mt6620_fm_config.rx_cfg.pamd_th)
1325 && (ATDC <= mt6620_fm_config.rx_cfg.atdc_th)
1326 && (MR >= mt6620_fm_config.rx_cfg.mr_th)
1327 && (PRX >= mt6620_fm_config.rx_cfg.prx_th)
1328 && (softmuteGainLvl <= mt6620_fm_config.rx_cfg.smg_th))
1340 WCN_DBG(FM_ALT | CHIP, "smt get CQI failed\n");
1343 WCN_DBG(FM_NTC | CHIP, "valid=%d\n",*valid);
1346 static fm_s32 mt6620_i2s_info_get(fm_s32 *ponoff, fm_s32 *pmode, fm_s32 *psample)
1350 FMR_ASSERT(psample);
1352 *ponoff = mt6620_i2s_inf.status;
1353 *pmode = mt6620_i2s_inf.mode;
1354 *psample = mt6620_i2s_inf.rate;
1359 static fm_s32 mt6620_hw_info_get(struct fm_hw_info *req)
1363 req->chip_id = mt6620_hw_info.chip_id;
1364 req->eco_ver = mt6620_hw_info.eco_ver;
1365 req->patch_ver = mt6620_hw_info.patch_ver;
1366 req->rom_ver = mt6620_hw_info.rom_ver;
1371 static fm_bool mt6620_em_test(fm_u16 group_idx, fm_u16 item_idx, fm_u32 item_value)
1375 WCN_DBG(FM_NTC | CHIP,"+%s():[group_idx=%d],[item_idx=%d],[item_value=%d]\n",
1376 __func__, group_idx, item_idx, item_value);
1380 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x01)))
1383 if(item_value == 1){
1384 if((ret = mt6620_set_bits(0xE0, 0x02, 0xFFFF)))
1387 if((ret = mt6620_set_bits(0xE0, 0x0, 0xFFFD)))
1390 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x0)))
1394 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x01)))
1396 if(item_value == 0){
1397 if((ret = mt6620_set_bits(0xE0, 0x0, 0xFFFD)))
1402 if((ret = mt6620_set_bits(0xD8, item_idx<<15, 0x7FFF)))
1406 if((ret = mt6620_set_bits(0xD8, 0, 0x7FFF)))
1411 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x0)))
1414 case RSSI_threshold:
1415 if((ret = mt6620_set_bits(0xe0, item_value, 0xFC00)))
1419 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x01)))
1422 if((ret = mt6620_set_bits(0xCF, 0x10, 0xFFFF)))
1425 if((ret = mt6620_set_bits(0xCF, 0x0, 0xFFEF)))
1428 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x0)))
1431 case PAMD_threshold:
1432 if((ret = mt6620_set_bits(0xE1, item_value, 0xFF00)))
1435 case Softmute_Enable:
1436 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x01)))
1439 if((ret = mt6620_set_bits(0xCF, 0x0020, 0xFFFF))) //1:CF[5] = 1
1442 if((ret = mt6620_set_bits(0xCF, 0x0000, 0xFFDF))) //1:CF[5] = 0
1445 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x0)))
1449 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x01)))
1452 if((ret = mt6620_set_bits(0xd4, 0x2000, 0xCFFF)))
1454 }else if(item_idx == 1){
1455 if((ret = mt6620_set_bits(0xd4, 0x1000, 0xCFFF)))
1457 }else if(item_idx == 0){
1458 if((ret = mt6620_set_bits(0xd4, 0x0000, 0xCFFF)))
1461 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x0)))
1467 if((ret = mt6620_set_bits(0xCB, 0x11, 0xFFFE)))
1469 if((ret = mt6620_set_bits(0xF, 0x0400, 0xFBFF)))
1471 }else if(item_idx == 1){
1473 if((ret = mt6620_set_bits(0xCB, 0x10, 0xFFFE)))
1475 if((ret = mt6620_set_bits(0xF, 0x0, 0xFBFF)))
1480 case Dynamic_Limiter:
1481 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x01)))
1484 if((ret = mt6620_set_bits(0xFA, 0x0, 0xFFF7)))
1487 if((ret = mt6620_set_bits(0xFA, 0x08, 0xFFF7)))
1490 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x0)))
1495 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x01)))
1497 if((ret = mt6620_set_bits(0xc8, item_value<<8, 0x80FF)))
1499 if((ret = mt6620_write(FM_MAIN_PGSEL, 0x0)))
1505 if((ret = mt6620_set_bits(0x63, 0x0400, 0xFBFF)))
1508 if((ret = mt6620_set_bits(0x63, 0x0, 0xFBFF)))
1514 case Softmute_Level:
1515 mt6620_write(FM_MAIN_PGSEL, 0x01);
1516 if(item_value > 0x24)
1518 mt6620_set_bits(0xD1, item_value, 0xFFC0);
1519 mt6620_write(FM_MAIN_PGSEL, 0x0);
1523 if((ret = mt6620_set_bits(0x9C, item_value<<8, 0xC0FF)))
1532 WCN_DBG(FM_NTC | CHIP,"-%s():[ret=%d]\n", __func__, ret);
1537 static const fm_u16 DesenseChMap[] = {
1538 0x0000, 0x0000, 0x0000, 0x0000, /* 7675~7600, 7755~7680, 7835~7760, 7915~7840 */
1539 0x0000, 0x0000, 0x0000, 0x0000, /* 7995~7920, 8075~8000, 8155~8080, 8235~8160 */
1540 0x0000, 0x0000, 0x0000, 0x0000, /* 8315~8240, 8395~8320, 8475~8400, 8555~8480 */
1541 0x0000, 0x0000, 0x0000, 0x0400, /* 8635~8560, 8715~8640, 8795~8720, 8875~8800 */
1542 0x0000, 0x0000, 0x0000, 0x0000, /* 8955~8880, 9035~8960, 9115~9040, 9195~9120 */
1543 0x00FC, 0x0000, 0x0000, 0x1C00, /* 9275~9200, 9355~9280, 9435~9360, 9515~9440 */
1544 0x0000, 0x0001, 0x0000, 0x0000, /* 9595~9520, 9675~9600, 9755~9680, 9835~9760 */
1545 0x0000, 0x7800, 0x0000, 0x0000, /* 9915~9840, 9995~9920, 10075~10000, 10155~10080 */
1546 0x0000, 0x0000, 0x0000, 0x0000, /* 10235~10160, 10315~10240, 10395~10320, 10475~10400 */
1547 0x0000, 0x0000, 0x0000, 0x0000, /* 10555~10480, 10635~10560, 10715~10640, 10795~10720 */
1548 0x0000 /* 10875~10800 */
1550 // return value: 0, not a de-sense channel; 1, this is a de-sense channel; else error no
1551 static fm_s32 mt6620_is_dese_chan(fm_u16 freq)
1553 fm_u8 bDesenseCh = 0;
1555 //caculate and applye compensation
1556 if (0 == fm_get_channel_space(freq))
1560 WCN_DBG(FM_NTC | CHIP,"%s, freq=%d\n",__func__,freq);
1562 bDesenseCh = ((0x0001 << (((freq - 7600)%80)/5)) & DesenseChMap[((freq - 7600)/80)])>>(((freq - 7600)%80)/5);
1563 WCN_DBG(FM_NTC | CHIP,"freq[%d] desense=[%d]\n",freq,bDesenseCh);
1569 1, is desense channel and rssi is less than threshold;
1570 0, not desense channel or it is but rssi is more than threshold.*/
1571 static fm_s32 mt6620_desense_check(fm_u16 freq,fm_s32 rssi)
1573 if(mt6620_is_dese_chan(freq))
1575 if(rssi<mt6620_fm_config.rx_cfg.desene_rssi_th)
1582 static fm_s32 MT6620fm_low_power_wa_default(fm_s32 fmon)
1587 fm_s32 MT6620fm_low_ops_register(struct fm_lowlevel_ops *ops)
1593 FMR_ASSERT(ops->cb.cur_freq_get);
1594 FMR_ASSERT(ops->cb.cur_freq_set);
1595 fm_cb_op = &ops->cb;
1597 ops->bi.low_pwr_wa = MT6620fm_low_power_wa_default;
1598 ops->bi.pwron = mt6620_pwron;
1599 ops->bi.pwroff = mt6620_pwroff;
1600 ops->bi.msdelay = Delayms;
1601 ops->bi.usdelay = Delayus;
1602 ops->bi.read = mt6620_read;
1603 ops->bi.write = mt6620_write;
1604 ops->bi.setbits = mt6620_set_bits;
1605 ops->bi.chipid_get = mt6620_get_chipid;
1606 ops->bi.mute = mt6620_Mute;
1607 ops->bi.rampdown = mt6620_RampDown;
1608 ops->bi.pwrupseq = mt6620_PowerUp;
1609 ops->bi.pwrdownseq = mt6620_PowerDown;
1610 ops->bi.setfreq = mt6620_SetFreq;
1611 ops->bi.seek = mt6620_Seek;
1612 ops->bi.seekstop = mt6620_SeekStop;
1613 ops->bi.scan = mt6620_Scan;
1614 ops->bi.scanstop = mt6620_ScanStop;
1615 ops->bi.rssiget = mt6620_GetCurRSSI;
1616 ops->bi.volset = mt6620_SetVol;
1617 ops->bi.volget = mt6620_GetVol;
1618 ops->bi.dumpreg = mt6620_dump_reg;
1619 ops->bi.msget = mt6620_GetMonoStereo;
1620 ops->bi.msset = MT6620_SetMonoStereo;
1621 ops->bi.pamdget = mt6620_GetCurPamd;
1622 ops->bi.em = mt6620_em_test;
1623 ops->bi.anaswitch = mt6620_SetAntennaType;
1624 ops->bi.anaget = mt6620_GetAntennaType;
1625 ops->bi.caparray_get = mt6620_GetCapArray;
1626 ops->bi.i2s_set = mt6620_I2s_Setting;
1627 ops->bi.i2s_get = mt6620_i2s_info_get;
1628 ops->bi.is_dese_chan = mt6620_is_dese_chan;
1629 ops->bi.softmute_tune = mt6620_soft_mute_tune;
1630 ops->bi.desense_check = mt6620_desense_check;
1631 ops->bi.get_freq_cqi = mt6620_GetFreqCQI;
1632 ops->bi.hwinfo_get = mt6620_hw_info_get;
1633 ops->bi.fm_via_bt = MT6620_FMOverBT;
1634 /*****tx function****/
1635 ops->bi.tx_support = mt6620_Tx_Support;
1636 ops->bi.pwrupseq_tx = mt6620_PowerUpTx;
1637 ops->bi.tune_tx = MT6620_SetFreq_Tx;
1638 ops->bi.pwrdownseq_tx = mt6620_PowerDownTx;
1639 ops->bi.tx_scan = mt6620_TxScan;
1640 ops->ri.rds_tx = MT6620_Rds_Tx;
1641 ops->ri.rds_tx_enable = MT6620_Rds_Tx_Enable;
1642 ops->ri.rds_tx_disable = MT6620_Rds_Tx_Disable;
1643 ops->ri.rdstx_support = mt6620_rdsTx_Support;
1644 ops->bi.tx_pwr_ctrl = MT6620_TX_PWR_CTRL;
1645 ops->bi.rtc_drift_ctrl = MT6620_RTC_Drift_CTRL;
1646 ops->bi.tx_desense_wifi = MT6620_TX_DESENSE;
1648 cmd_buf_lock = fm_lock_create("20_cmd");
1649 ret = fm_lock_get(cmd_buf_lock);
1651 cmd_buf = fm_zalloc(TX_BUF_SIZE + 1);
1654 WCN_DBG(FM_ALT | CHIP, "6620 fm lib alloc tx buf failed\n");
1658 #if 0//def MTK_FM_50KHZ_SUPPORT
1659 cqi_fifo = fm_fifo_create("6620_cqi_fifo", sizeof(struct adapt_fm_cqi), 640);
1661 WCN_DBG(FM_ALT | CHIP, "6620 fm lib create cqi fifo failed\n");
1669 fm_s32 MT6620fm_low_ops_unregister(struct fm_lowlevel_ops *ops)
1673 #if 0//def MTK_FM_50KHZ_SUPPORT
1674 fm_fifo_release(cqi_fifo);
1682 ret = fm_lock_put(cmd_buf_lock);
1686 fm_memset(&ops->bi, 0, sizeof(struct fm_basic_interface));
1691 /***********************************************************************
1692 * Hi-Lo Side Injection
1694 ***********************************************************************/
1695 fm_s32 MT6620_HL_Side_Adj(fm_u16 freq, fm_s32 *hl)
1702 static fm_u16 Hi_Channels[] = {7950, 8070, 8210, 10640};
1704 if (0 == fm_get_channel_space(freq)) {
1708 WCN_DBG(FM_DBG | CHIP,"+%s, [freq=%d]\n", __func__, (fm_s32)freq);
1712 if(sizeof(Hi_Channels) == 0)
1715 tblsize = sizeof(Hi_Channels)/sizeof(Hi_Channels[0]);
1716 for(indx = 0; indx < tblsize; indx++){
1717 if(Hi_Channels[indx] == freq)
1727 //Set high-side injection (AFC)
1728 if((ret = mt6620_read(0x0F, &tmp)))
1730 if((ret = mt6620_write(0x0F, tmp |0x0400)))
1732 if((ret = mt6620_write(FM_MAIN_PGSEL, 0)))
1734 //Set high-side injection (DFE)
1735 if((ret = mt6620_read(0xCB, &tmp)))
1737 if((ret = mt6620_write(0xCB, tmp | 0x01)))
1739 //mt6620_write(0xCB, dataRead&0xFFFE);
1741 //Set low-side injection (AFC)
1742 if((ret = mt6620_read(0x0F, &tmp)))
1744 if((ret = mt6620_write(0x0F, tmp&0xFBFF)))
1746 if((ret = mt6620_write(FM_MAIN_PGSEL, 0)))
1748 //Set low-side injection (DFE)
1749 if((ret = mt6620_read(0xCB, &tmp)))
1751 //mt6620_write(0xCB, dataRead | 0x01);
1752 if((ret = mt6620_write(0xCB, tmp&0xFFFE)))
1756 WCN_DBG(FM_NTC | CHIP,"-%s, [isHiSide=%d][ret=%d]\n", __func__, (fm_s32)isHiSide, ret);
1760 /***********************************************************************
1761 * ADPLL Power On or Off
1763 ***********************************************************************/
1764 fm_s32 MT6620_ADPLL_Power_OnOff(fm_s32 onoff, fm_s32 ADPLL_clk)
1771 if((ret = mt6620_write(0x25, 0x040F)))
1773 //Remove the Reset_N
1774 if((ret = mt6620_write(0x20, 0x2720)))
1776 // change DLF loop gain
1777 // Set FMCR_DLF_GAIN_A = "9"
1778 // Set FMCR_DLF_GAIN_B = "9"
1779 if((ret = mt6620_write(0x22, 0x9980)))
1781 //Configure initial I_CODE for calibration
1782 if((ret = mt6620_write(0x25, 0x080F)))
1785 //Set FMCR_DCO_ EN = "1
1786 if(ADPLL_clk == FM_ADPLL_16M){
1787 if((ret = mt6620_write(0x1E, 0x0A63)))
1791 if((ret = mt6620_write(0x1E, 0x0A65)))
1795 if((ret = mt6620_write(0x1E, 0x0A71)))
1797 }else if(ADPLL_clk == FM_ADPLL_15M){
1798 if((ret = mt6620_write(0x1E, 0x0863)))
1802 if((ret = mt6620_write(0x1E, 0x0865)))
1806 if((ret = mt6620_write(0x1E, 0x0871)))
1814 if((ret = mt6620_write(0x2A, 0x1026)))
1818 //ADPLL Power Off Sequence
1820 // Set rgfrf_top_ck = "0"
1821 if((ret = mt6620_set_bits(0x2A, 0, MASK(12))))//set 2A D12=0
1823 // Set FMCR_OPEN_LOOP_EN = "0"
1824 // Set FMCR_PLL_EN = "0"
1825 // Set FMCR_DCO_EN = "0"
1826 if((ret = mt6620_set_bits(0x1E, 0, MASK(7)&MASK(4)&MASK(0))))//set 1E D7 D4 D0=0
1828 // Set rgfrf_adpll_reset_n = "0"
1829 if((ret = mt6620_set_bits(0x20, 0, MASK(13))))//set 20 D13=0
1831 // Set rgfrf_adpll_reset_n = "1"
1832 if((ret = mt6620_set_bits(0x20, BITn(13), MASK(13))))//set 20 D13=1
1842 /***********************************************************************
1843 * Frequency Avoidance
1845 ***********************************************************************/
1846 fm_s32 MT6620_ADPLL_Freq_Avoid(fm_u16 freq, fm_s32 *freqavoid)
1849 fm_s32 ADPLL_clk = FM_ADPLL_15M;
1850 fm_u16 dataRead = 0;
1852 static fm_u16 Avoid_Channels[] ={
1853 7670, 7680, 7690, 7700, 8060, 8070, 8080, 8440, 8450, 8460, 8720, 8830, 8840, 9200,
1854 9210, 9220, 9230, 9360, 9490, 9600, 9610, 9980, 9990, 10000, 10130, 10360, 10370, 10380, 10740,
1858 if (0 == fm_get_channel_space(freq)) {
1862 WCN_DBG(FM_DBG | CHIP,"+%s, [freq=%d]\n", __func__, (fm_s32)freq);
1866 dataRead = sizeof(Avoid_Channels)/sizeof(Avoid_Channels[0]);
1868 while((indx < dataRead) && (ADPLL_clk != FM_ADPLL_16M)){
1869 if(Avoid_Channels[indx] == freq){
1870 ADPLL_clk = FM_ADPLL_16M;
1876 if((ret = mt6620_read(0x1E, &dataRead)))
1878 if(((dataRead&BITn(9))&&(ADPLL_clk == FM_ADPLL_16M))||(!(dataRead&BITn(9))&&(ADPLL_clk == FM_ADPLL_15M)))//1EH, D9
1879 goto out; //we need not do freq avoid at these caes
1881 if(ADPLL_clk == FM_ADPLL_16M){
1882 //Set rgf_f16mode_en = X
1883 if((ret = mt6620_set_bits(0x61, BITn(0), MASK(0))))//set 61H D0=1, 16.384MHZ
1885 }else if(ADPLL_clk == FM_ADPLL_15M){
1886 //Set rgf_f16mode_en = X
1887 if((ret = mt6620_set_bits(0x61, 0, MASK(0))))//set 61H D0=0, 15.36MHZ
1895 ret = MT6620_ADPLL_Power_OnOff(FM_ADPLL_OFF, ADPLL_clk);
1897 WCN_DBG(FM_NTC | CHIP,"%s, ADPLL OFF failed, [ret=%d]n", __func__, ret);
1901 //Set FMCR_DCO_CK_SEL = ? (default = 0, 15.36)
1902 if(ADPLL_clk == FM_ADPLL_16M){
1903 if((ret = mt6620_set_bits(0x1E, BITn(9), MASK(9))))//set 1EH D9=1, 16.384MHZ
1905 }else if(ADPLL_clk == FM_ADPLL_15M){
1906 if((ret = mt6620_set_bits(0x1E, 0, MASK(9))))//set 1EH D9=0, 15.36MHZ
1914 ret = MT6620_ADPLL_Power_OnOff(FM_ADPLL_ON, ADPLL_clk);
1916 WCN_DBG(FM_NTC | CHIP,"%s, ADPLL ON failed, [ret=%d]\n", __func__, ret);
1919 //Set rgfrf_cnt_resync_b = 0
1920 if((ret = mt6620_set_bits(0x2A, 0, MASK(1))))//set 2AH D1=0
1922 //Set rgfrf_cnt_resync_b = 1
1923 if((ret = mt6620_set_bits(0x2A, BITn(1), MASK(1))))//set 2AH D1=1
1926 WCN_DBG(FM_NTC | CHIP,"-%s, [ADPLL_clk=%d][ret=%d]\n", __func__, (fm_s32)ADPLL_clk, ret);
1930 /***********************************************************************
1931 * Frequency Avoidance
1933 ***********************************************************************/
1934 fm_s32 MT6620_MCU_Freq_Avoid(fm_u16 freq, fm_s32 *freqavoid)
1937 fm_s32 mcuDsense = FM_MCU_DESE_DISABLE;
1940 static fm_u16 FreqList[] ={7800, 7940, 8320, 9260, 9600, 10400};
1942 if (0 == fm_get_channel_space(freq)) {
1946 WCN_DBG(FM_DBG | CHIP,"+%s, [freq=%d]\n", __func__, (fm_s32)freq);
1950 len = sizeof(FreqList)/sizeof(FreqList[0]);
1952 while((indx < len) && (mcuDsense != FM_MCU_DESE_ENABLE)){
1953 if(FreqList[indx] == freq){
1954 mcuDsense = FM_MCU_DESE_ENABLE;
1960 if(mcuDsense == FM_MCU_DESE_DISABLE){
1961 if(mtk_wcn_wmt_dsns_ctrl(WMTDSNS_FM_DISABLE)){
1966 }else if(mcuDsense == FM_MCU_DESE_ENABLE){
1967 if(mtk_wcn_wmt_dsns_ctrl(WMTDSNS_FM_ENABLE)){
1973 WCN_DBG(FM_ERR | CHIP,"para error!\n");
1977 WCN_DBG(FM_NTC | CHIP,"-%s, [mcuDsense=%d][ret=%d]\n", __func__, (fm_s32)mcuDsense, ret);
1981 /***********************************************************************
1984 ***********************************************************************/
1985 fm_s32 MT6620_TX_PWR_CTRL(fm_u16 freq, fm_s32 *ctr)
1987 #define MT6620_TX_PWR_LEV_MAX 120
1988 #define MT6620_TX_PWR_LEV_MIN 85
1995 WCN_DBG(FM_DBG | CHIP,"+%s, [freq=%d]\n", __func__, (fm_s32)freq);
1997 if(freq < FM_TX_PWR_CTRL_FREQ_THR){
1998 //Power setting - 1dB, 3C(HEX)=A9E9
2001 //Power setting -2 dB, 3C(HEX)=A8E9
2005 if(*ctr > MT6620_TX_PWR_LEV_MAX){
2006 *ctr = MT6620_TX_PWR_LEV_MAX;
2007 }else if(*ctr < MT6620_TX_PWR_LEV_MIN){
2008 *ctr = MT6620_TX_PWR_LEV_MIN;
2010 fine = 43017 + ((1<<((*ctr-85)%6))-1)*32;
2011 WCN_DBG(FM_DBG | CHIP,"0x3C = 0x%04x \n", fine);
2012 coarse = 514 + ((1<<((*ctr-85)/6))-1)*4;
2013 WCN_DBG(FM_DBG | CHIP,"0x3D = 0x%04x \n", coarse);
2015 if((ret = mt6620_write(0x3C, fine)))
2017 if((ret = mt6620_write(0x3D, coarse)))
2020 tmp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ);
2021 if((ret = mt6620_read(0x9C, ®)))
2024 if(tmp < FM_TX_PWR_CTRL_TMP_THR_DOWN){
2025 reg |= (0x1C << 8); //9CH, D13~D8 = 1C
2026 }else if(tmp > FM_TX_PWR_CTRL_TMP_THR_UP){
2027 reg |= (0x33 << 8); //9CH, D13~D8 ==33
2029 reg |= (0x25 << 8); //9CH, D13~D8 =25
2031 if((ret = mt6620_write(0x9C, reg)))
2035 WCN_DBG(FM_NTC | CHIP,"-%s, [temp=%d][ret=%d]\n", __func__, (fm_s32)tmp, ret);
2039 /***********************************************************************
2042 ***********************************************************************/
2043 fm_s32 MT6620_RTC_Drift_CTRL(fm_u16 freq, fm_s32 *ctr)
2047 fm_s32 chanel_resolution = 1;
2048 fm_s16 compensation_int16 = 0;
2050 fm_s32 drift = *ctr;
2052 WCN_DBG(FM_DBG | CHIP,"+%s, [freq=%d]\n", __func__, (fm_s32)freq);
2054 //turn off VCO tracking
2055 if((ret = mt6620_set_bits(0x48, 0, MASK(15))))//set 48 D15=0
2058 //get channel resolution
2059 if((ret = mt6620_read(0x46, ®)))
2064 chanel_resolution = 1024;
2067 chanel_resolution = 512;
2070 chanel_resolution = 256;
2073 chanel_resolution = 128;
2076 WCN_DBG(FM_ERR | CHIP,"chanel_resolution error[%d]\n", (fm_s32)(reg >> 14));
2080 //caculate and applye compensation
2081 if (0 == fm_get_channel_space(freq)) {
2084 WCN_DBG(FM_DBG | CHIP,"[resolution=%d][freq=%d][drift=%d]\n", chanel_resolution, (fm_s32)(freq/100), (*ctr));
2085 tmp = (2*drift*(freq/100))/chanel_resolution;
2086 compensation_int16 = (fm_s16)tmp;
2087 if(compensation_int16 >= 511){
2088 compensation_int16 = 511;
2089 }else if(compensation_int16 <= -512){
2090 compensation_int16 = -512;
2092 if((ret = mt6620_read(0x47, ®)))
2095 reg |= (compensation_int16 << 6);
2096 if((ret = mt6620_write(0x47, reg)))
2100 //turn on VCO tracking
2101 if((ret = mt6620_set_bits(0x48, BITn(15), MASK(15))))//set 48 D15=1
2105 WCN_DBG(FM_NTC | CHIP,"-%s, [compensation=%d][ret=%d]\n", __func__, (fm_s32)(compensation_int16), ret);
2109 /***********************************************************************
2110 * TX desense with WIFI/BT
2112 ***********************************************************************/
2113 fm_s32 MT6620_TX_DESENSE(fm_u16 freq, fm_s32 *ctr)
2116 fm_u16 dataRead = 0;
2119 WCN_DBG(FM_DBG|CHIP,"+%s, [freq=%d]\n", __func__, (fm_s32)freq);
2121 // enable FM TX VCO tracking
2122 if((ret = mt6620_read(0x29, &dataRead)))//read 29
2124 WCN_DBG(FM_NTC | CHIP,"Before VCO On, [0x29=0x%04x]\n", dataRead);
2125 if((ret = mt6620_read(0x12, &dataRead)))//read 12
2127 WCN_DBG(FM_NTC | CHIP,"Before VCO On, [0x12=0x%04x]\n", dataRead);
2129 if((ret = mt6620_set_bits(0x12, 0, MASK(15))))//set 12 D15=0
2131 if((ret = mt6620_set_bits(0x41, BITn(0), MASK(0))))//set 41 D0=1
2133 if((ret = mt6620_set_bits(0x48, BITn(15), MASK(15))))//set 48 D15=1
2136 // wait 100ms (VCO tracking 100ms)
2137 if(*ctr > FM_TX_TRACKING_TIME_MAX){
2138 *ctr = FM_TX_TRACKING_TIME_MAX;
2142 // disable FM TX VCO tracking
2143 if((ret = mt6620_set_bits(0x28, BITn(2), MASK(2))))//set 28 D2=1
2145 if((ret = mt6620_read(0x29, &dataRead)))//read 29 D11~D0
2147 WCN_DBG(FM_NTC | CHIP,"Before VCO Off, [0x29=0x%04x]\n", dataRead);
2148 tmp = dataRead&0x0FFF; // Read 0x29 D11~D0
2149 if((ret = mt6620_read(0x12, &dataRead)))//read 12
2151 //Set 0x12 D15 to 1, D11:D0 to read(0x29 D11~D0)
2155 if((ret = mt6620_write(0x12, dataRead)))
2157 WCN_DBG(FM_NTC | CHIP,"Before VCO Off, [0x12=0x%04x]\n", dataRead);
2158 if((ret = mt6620_set_bits(0x48, 0, MASK(15))))//set 48 D15=0
2160 if((ret = mt6620_set_bits(0x41, 0, MASK(0))))//set 41 D0=0
2164 WCN_DBG(FM_DBG | CHIP,"-%s, [freq=%d][delay=%dms][ret=%d]\n", __func__, (fm_s32)freq, *ctr, ret);
2168 static fm_s32 MT6620_Rds_Tx_Enable(void)
2170 mt6620_write(0x9F, 0x0000);
2171 mt6620_write(0xAB, 0x3872);
2172 mt6620_write(0xAC, 0x3B3A);
2173 mt6620_write(0xAD, 0x0113);
2174 mt6620_write(0xAE, 0x03B2);
2175 mt6620_write(0xAF, 0x0001);
2176 mt6620_write(0xB1, 0x63EB);
2177 mt6620_write(0xF4, 0x0020);
2178 mt6620_write(0xF5, 0x3222);
2183 static fm_s32 MT6620_Rds_Tx_Disable(void)
2185 mt6620_write(0x9F, 0x0000);
2186 mt6620_write(0xAB, 0x39B6);
2187 mt6620_write(0xAC, 0x3C3E);
2188 mt6620_write(0xAD, 0x0000);
2189 mt6620_write(0xAE, 0x03C2);
2190 mt6620_write(0xAF, 0x0001);
2191 mt6620_write(0xF4, 0x0020);
2192 mt6620_write(0xF5, 0xBF16);
2193 mt6620_write(0xB1, 0x623D);
2198 static fm_s32 MT6620_Rds_Tx(fm_u16 pi, fm_u16 *ps, fm_u16 *other_rds, fm_u8 other_rds_cnt)
2201 fm_u16 pkt_size = 0;
2203 WCN_DBG(FM_NTC | RDSC, "+%s():PI=0x%04x, PS=0x%04x/0x%04x/0x%04x, other_rds_cnt=%d \n",__func__, pi, ps[0], ps[1], ps[2], other_rds_cnt);
2204 if (FM_LOCK(cmd_buf_lock))
2206 pkt_size = mt6620_rds_tx(cmd_buf, TX_BUF_SIZE, pi, ps, other_rds, other_rds_cnt);
2207 ret = fm_cmd_tx(cmd_buf, pkt_size, FLAG_RDS_TX, SW_RETRY_CNT, RDS_TX_TIMEOUT, NULL);
2208 FM_UNLOCK(cmd_buf_lock);