1 #include <linux/semaphore.h>
2 #include <linux/delay.h>
3 #include <linux/slab.h>
5 #include "fm_typedef.h"
8 #include "fm_interface.h"
11 #include "fm_config.h"
13 #include "mt6626_fm_reg.h"
14 #include "mt6626_fm.h"
15 #include "mt6626_drv_dsp.h"
16 #include "mt6626_fm_link.h"
17 #include "mt6626_fm_lib.h"
18 #include "mt6626_fm_cmd.h"
20 #define MT6626_FM_PATCH_PATH "/etc/firmware/mt6626_fm_patch.bin"
21 #define MT6626_FM_COEFF_PATH "/etc/firmware/mt6626_fm_coeff.bin"
22 #define MT6626_FM_HWCOEFF_PATH "/etc/firmware/mt6626_fm_hwcoeff.bin"
23 #define MT6626_FM_ROM_PATH "/etc/firmware/mt6626_fm_rom.bin"
25 extern void fm_low_power_wa(int fmon);
26 extern void mt66x6_poweron(int idx);
27 extern void mt66x6_poweroff(int idx);
29 static struct fm_callback *fm_cb_op;
31 /* mt6626 FM Receiver Power Up Sequence*/
32 static const struct ctrl_word_operation PowerOnSetting[] = {
33 //@Wholechip FM Power Up: FM Digital Clock enable
36 {MSDELAY, 0x0, 0x0003},//Delay 3ms
39 {HW_VER, 0x99, 0x0000},
40 //antenna and audio path config
41 #ifdef FMRADIO_I2S_SUPPORT
42 #ifdef FM_PowerOn_with_ShortAntenna
43 {0x61, 0xFF73, 0x0090},//no low power mode, I2S, short antenna
45 {0x61, 0xFF73, 0x0080},//no low power mode, I2S, long antenna
47 {0x9B, 0xFFF7, 0x0008},//0000->master, 0008->slave
48 {0x5F, 0xE7FF, 0x0000},//0000->32K, 0800->44.1K, 1000->48K
49 //{0x61, 0xFF73, 0x0080},//no low power mode, I2S, long antenna, 0xff63
50 //{0x9B, 0xFFF7, 0x0008},//0000->master, 0008->slave
51 //{0x5F, 0xE7FF, 0x0000},//0000->32K, 0800->44.1K, 1000->48K
53 #ifdef FM_PowerOn_with_ShortAntenna
54 {0x61, 0xFF63, 0x0010},//no low power mode, analog line in, short antenna
56 {0x61, 0xFF63, 0x0000},//no low power mode, analog line in, long antenna
59 {HW_VER, 0x0062, 0x0000},//read the HW version
61 //@Wholechip FM Power Up: FM Digital Init: download patch/DSP coefficient/HWACC coefficient
62 {DSPPATCH, 0x0, DSP_PATH},
63 {DSPPATCH, 0x0, DSP_COEFF},
64 {DSPPATCH, 0x0, DSP_HW_COEFF},
68 //@Wholechip FM Power Up: FM Digital Init: fm_rgf_maincon
72 {0x61, 0xFFFF, 0x0002},
73 {0x61, 0xFFFE, 0x0000},
76 #define POWER_ON_COMMAND_COUNT (sizeof(PowerOnSetting)/sizeof(PowerOnSetting[0]))
78 static int Chip_Version = mt6626_E1;
81 static fm_s32 mt6626_pwron(fm_s32 data)
83 mt66x6_poweron(MT66x6_FM);
88 static fm_s32 mt6626_pwroff(fm_s32 data)
90 mt66x6_poweroff(MT66x6_FM);
94 static fm_s32 Delayms(fm_u32 data)
96 WCN_DBG(FM_DBG | CHIP, "delay %dms\n", data);
101 static fm_s32 Delayus(fm_u32 data)
103 WCN_DBG(FM_DBG | CHIP, "delay %dus\n", data);
108 static fm_s32 mt6626_read(fm_u8 addr, fm_u16 *val)
112 ret = fm_ctrl_rx(addr, val);
115 WCN_DBG(FM_ALT | CHIP, "rd 0x%02x err\n", addr);
119 WCN_DBG(FM_DBG | CHIP, "rd 0x%02x 0x%04x\n", addr, *val);
123 static fm_s32 mt6626_write(fm_u8 addr, fm_u16 val)
127 ret = fm_ctrl_tx(addr, val);
130 WCN_DBG(FM_ALT | CHIP, "wr 0x%02x err\n", addr);
134 WCN_DBG(FM_DBG | CHIP, "wr 0x%02x 0x%04x\n", addr, val);
138 static fm_s32 mt6626_write1(fm_u8 addr, fm_u16 val)
140 return fm_ctrl_tx(addr, val);
143 static fm_s32 mt6626_set_bits(fm_u8 addr, fm_u16 bits, fm_u16 mask)
148 ret = mt6626_read(addr, &val);
153 val = ((val & (mask)) | bits);
154 ret = mt6626_write(addr, val);
159 static fm_u16 mt6626_get_chipid(void)
164 static void mt6626_TUNE_ON(void)
168 WCN_DBG(FM_DBG | CHIP, "tune on\n");
169 mt6626_read(FM_MAIN_CTRL, &dataRead);
170 //mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFFE)|TUNE);
171 mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFF8) | TUNE);
174 static void mt6626_SEEK_ON(void)
178 WCN_DBG(FM_DBG | CHIP, "seek on\n");
179 mt6626_read(FM_MAIN_CTRL, &dataRead);
180 //mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFFD)|SEEK);
181 mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFF8) | SEEK);
184 static void mt6626_SCAN_ON(void)
188 WCN_DBG(FM_DBG | CHIP, "scan on\n");
189 mt6626_read(FM_MAIN_CTRL, &dataRead);
190 //mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFFB)|SCAN);
191 mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFF8) | SCAN);
194 /* MT6628_SetAntennaType - set Antenna type
195 * @type - 1,Short Antenna; 0, Long Antenna
197 static fm_s32 mt6626_SetAntennaType(fm_s32 type)
201 WCN_DBG(FM_DBG | CHIP, "set ana to %s\n", type ? "short" : "long");
202 mt6626_read(FM_MAIN_CG2_CTRL, &dataRead);
205 dataRead |= ANTENNA_TYPE;
207 dataRead &= (~ANTENNA_TYPE);
210 mt6626_write(FM_MAIN_CG2_CTRL, dataRead);
215 static fm_s32 mt6626_GetAntennaType(void)
219 mt6626_read(FM_MAIN_CG2_CTRL, &dataRead);
220 WCN_DBG(FM_DBG | CHIP, "get ana type: %s\n", (dataRead&ANTENNA_TYPE) ? "short" : "long");
222 if (dataRead&ANTENNA_TYPE)
223 return FM_SHORT_ANA; //short antenna
225 return FM_LONG_ANA; //long antenna
228 static fm_s32 mt6626_writeFA(fm_u16 *buff, fm_u8 fa)
232 for (i = 0; i < 3; i++) {
234 *buff |= (1 << (12 + i));
236 *buff &= ~(1 << (12 + i));
242 static fm_s32 mt6626_Mute(fm_bool mute)
246 WCN_DBG(FM_DBG | CHIP, "set %s\n", mute ? "mute" : "unmute");
247 mt6626_read(FM_MAIN_CTRL, &dataRead);
250 mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFDF) | 0x0020);
252 mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFDF));
259 * mt6626_WaitSTCDone - wait for stc done flag change to '1'
260 * @waittime - the total wait time in ms
261 * @interval - the delay time of every polling loop in ms
262 * if success, return 0; else error code
264 static fm_s32 mt6626_WaitSTCDone(fm_u32 waittime, fm_u32 interval)
270 cnt = waittime / interval;
277 return -1; //wait for STC done failed
281 mt6626_read(FM_MAIN_INTR, &dataRead);
282 } while ((dataRead&FM_INTR_STC_DONE) == 0);
287 static fm_s32 mt6626_ClearSTCDone(void)
291 mt6626_read(FM_MAIN_INTR, &dataRead);
292 mt6626_write(FM_MAIN_INTR, dataRead | FM_INTR_STC_DONE);//clear status flag
296 static fm_s32 mt6626_RampDown(void)
300 WCN_DBG(FM_DBG | CHIP, "ramp down\n");
302 mt6626_read(FM_MAIN_CTRL, &dataRead);
303 mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFF0)); //clear rgf_tune/seek/scan/dsp_init
305 //Set DSP ramp down state
306 mt6626_read(FM_MAIN_CTRL, &dataRead);
307 mt6626_write(FM_MAIN_CTRL, (dataRead | RAMP_DOWN));
309 //Check STC_DONE status flag (not the interrupt flag!)
310 if (mt6626_WaitSTCDone(1000, 1)) {
311 WCN_DBG(FM_ALT | CHIP, "ramp down failed\n");
315 //Clear DSP ramp down state
316 mt6626_read(FM_MAIN_CTRL, &dataRead);
317 mt6626_write(FM_MAIN_CTRL, (dataRead&(~RAMP_DOWN)));
319 mt6626_ClearSTCDone();
324 * mt6626_DspPatch - DSP download procedure
325 * @img - source dsp bin code
326 * @type - rom/patch/coefficient/hw_coefficient
329 static fm_s32 mt6626_DspPatch(const fm_u16 *img, enum IMG_TYPE type)
331 fm_u32 ctrl_code = 0;
332 fm_u16 data_len = 0; // in words
337 WCN_DBG(FM_DBG | CHIP, "down load DSP patch %d (1-rom, 2-patch, 3-coe, 4-hwcoe)\n", type);
340 case IMG_ROM: //rom code
341 case IMG_PATCH: //patch
344 case IMG_COEFFICIENT: //coeff
347 case IMG_HW_COEFFICIENT: //HW coeff
354 data_len = img[1] - img[0] + 1;
355 WCN_DBG(FM_DBG | CHIP, "patch len: %d\n", data_len);
357 if (!(data_len > 0)) {
362 mt6626_write(FM_DSP_PATCH_CTRL, 0);
363 mt6626_write(FM_DSP_PATCH_OFFSET, img[0]); //Start address
364 mt6626_write(FM_DSP_PATCH_CTRL, 0x40); //Reset download control
365 mt6626_write(FM_DSP_PATCH_CTRL, ctrl_code); //Set download control
370 case IMG_HW_COEFFICIENT:
371 WCN_DBG(FM_DBG | CHIP, "rom/patch/hw_coefficient downloading......\n");
373 for (i = 0; i < data_len; i++) {
374 mt6626_write1(FM_DSP_PATCH_DATA, img[2+i]);
378 case IMG_COEFFICIENT:
379 WCN_DBG(FM_DBG | CHIP, "coefficient downloading......\n");
381 if (MT6626_DEEMPHASIS_50us) {
382 for (i = 0; i < data_len; i++) {
384 mt6626_write1(FM_DSP_PATCH_DATA, fm_cust_config_fetch(FM_CFG_RX_RSSI_TH_LONG));
385 } else if (i == 292) {
386 mt6626_write1(FM_DSP_PATCH_DATA, 0x332B);
387 mt6626_write1(FM_DSP_PATCH_DATA, 0x2545);
388 mt6626_write1(FM_DSP_PATCH_DATA, 0x1344);
389 mt6626_write1(FM_DSP_PATCH_DATA, 0x09F5);
390 mt6626_write1(FM_DSP_PATCH_DATA, 0x0526);
391 mt6626_write1(FM_DSP_PATCH_DATA, 0x02A9);
392 mt6626_write1(FM_DSP_PATCH_DATA, 0x0160);
393 mt6626_write1(FM_DSP_PATCH_DATA, 0x00B6);
394 mt6626_write1(FM_DSP_PATCH_DATA, 0x005E);
395 mt6626_write1(FM_DSP_PATCH_DATA, 0x0031);
396 mt6626_write1(FM_DSP_PATCH_DATA, 0x0000);
397 mt6626_write1(FM_DSP_PATCH_DATA, 0x0000);
398 mt6626_write1(FM_DSP_PATCH_DATA, 0x0000);
400 } else if (i == 505) {
401 mt6626_write1(FM_DSP_PATCH_DATA, fm_cust_config_fetch(FM_CFG_RX_RSSI_TH_SHORT));
403 mt6626_write1(FM_DSP_PATCH_DATA, img[2+i]);
407 for (i = 0; i < data_len; i++) {
409 mt6626_write1(FM_DSP_PATCH_DATA, fm_cust_config_fetch(FM_CFG_RX_RSSI_TH_LONG));
410 } else if (i == 505) {
411 mt6626_write1(FM_DSP_PATCH_DATA, fm_cust_config_fetch(FM_CFG_RX_RSSI_TH_SHORT));
413 mt6626_write1(FM_DSP_PATCH_DATA, img[2+i]);
423 WCN_DBG(FM_DBG | CHIP, "down load DSP patch %d ok\n", type);
427 static fm_s32 mt6626_PowerUp(fm_u16 *chip_id, fm_u16 *device_id)
431 fm_u16 tmp_reg, cnt = 0;
433 const fm_u16 *bin_patch = NULL;
434 const fm_u16 *bin_coeff = NULL;
437 FMR_ASSERT(device_id);
439 WCN_DBG(FM_DBG | CHIP, "pwr on seq\n");
441 // mt6626 FM power on sequence
442 for (i = 0; i < POWER_ON_COMMAND_COUNT; i++) {
443 switch (PowerOnSetting[i].addr) {
444 case FM_PUS_DSPPATCH:
446 switch (PowerOnSetting[i].or) {
447 case DSP_PATH: //DSP path download
448 mt6626_DspPatch(bin_patch, IMG_PATCH);
450 case DSP_COEFF: //DSP coefficient download
451 mt6626_DspPatch(bin_coeff, IMG_COEFFICIENT);
453 case DSP_HW_COEFF: //DSP HW coefficient download
454 mt6626_DspPatch(bin_hw_coeff, IMG_HW_COEFFICIENT);
465 mt6626_read((fm_u8)PowerOnSetting[i].and, &tmp_reg);
466 tmp_reg &= PowerOnSetting[i].or;
472 } while ((tmp_reg == 0) && (cnt < (MT6626_MAX_COUNT << 1)));
474 if (cnt == (MT6626_MAX_COUNT << 1)) {
475 WCN_DBG(FM_ALT | CHIP, "polling status Active failed:0x%02X\n", (fm_u8)PowerOnSetting[i].and);
484 mt6626_read((fm_u8)PowerOnSetting[i].and, &tmp_reg);
485 tmp_reg &= PowerOnSetting[i].or;
491 } while ((tmp_reg != 0) && (cnt < MT6626_MAX_COUNT));
493 if (cnt == MT6626_MAX_COUNT) {
494 WCN_DBG(FM_ALT | CHIP, "polling status Negative failed:0x%02X\n", (fm_u8)PowerOnSetting[i].and);
500 Delayus(PowerOnSetting[i].or);
503 Delayms(PowerOnSetting[i].or);
507 switch (PowerOnSetting[i].and) {
509 mt6626_read(0x99, &tmp_reg);
513 Chip_Version = mt6626_E1;
514 bin_patch = bin_patch_E1;
515 bin_coeff = bin_coeff_E1;
519 Chip_Version = mt6626_E2;
520 bin_patch = bin_patch_E2;
521 bin_coeff = bin_coeff_E2;
527 mt6626_read((fm_u8)PowerOnSetting[i].and, &tmp_reg);
528 //record chip id & device id
530 *device_id = tmp_reg;
531 WCN_DBG(FM_NTC | CHIP, "chip_id:0x%04x\n", tmp_reg);
534 mt6626_read((fm_u8)PowerOnSetting[i].and, &tmp_reg);
536 if (PowerOnSetting[i].or) {
537 mt6626_write(PowerOnSetting[i].and, (tmp_reg | 0x8000));
539 mt6626_write(PowerOnSetting[i].and, (tmp_reg&0x7FFF));
550 if (PowerOnSetting[i].and != 0) {
551 if (mt6626_read((fm_u8)PowerOnSetting[i].addr, &tmp_reg)) {
552 WCN_DBG(FM_ALT | CHIP, "power up failed, can't read reg %02X\n", (fm_u8)PowerOnSetting[i].and);
556 tmp_reg &= PowerOnSetting[i].and;
557 tmp_reg |= PowerOnSetting[i].or;
559 tmp_reg = PowerOnSetting[i].or;
562 if (mt6626_write((fm_u8)PowerOnSetting[i].addr, tmp_reg)) {
563 WCN_DBG(FM_ALT | CHIP, "power up failed, can't write reg %02X\n", (fm_u8)PowerOnSetting[i].addr);
571 WCN_DBG(FM_DBG | CHIP, "pwr on seq done\n");
575 static fm_s32 mt6626_PowerDown(void)
581 /*SW work around for MCUFA issue.
582 *if interrupt happen before doing rampdown, DSP can't switch MCUFA back well.
583 * In case read interrupt, and clean if interrupt found before rampdown.
585 WCN_DBG(FM_DBG | CHIP, "pwr down seq\n");
586 mt6626_read(FM_MAIN_INTR, &dataRead);
588 if (dataRead & 0x1) {
589 mt6626_write(FM_MAIN_INTR, dataRead);//clear status flag
594 mt6626_write(0x60, 0x330F);
595 mt6626_write(FM_MAIN_CG2_CTRL, 1);
597 for (i = 0; i < 4; i++) {
598 mt6626_read(0x6E, &dataRead);
599 mt6626_write(0x6E, (dataRead&0xFFF8));
602 mt6626_write(FM_MAIN_CG1_CTRL, 0);
603 mt6626_write(FM_MAIN_CG1_CTRL, 0x4000);
604 mt6626_write(FM_MAIN_CG1_CTRL, 0);
609 static fm_bool mt6626_SetFreq(fm_u16 freq)
611 fm_u32 CHAN = 0x0000;
612 fm_u16 dataRead, cnt = 0, tempbuff = 0;
617 fm_cb_op->cur_freq_set(freq);
618 CHAN = (freq - 640) << 1;
619 mt6626_read(FM_CHANNEL_SET, &dataRead);
621 switch (Chip_Version) {
624 if (((fm_u8)((dataRead & 0x1000) >> 12)) ^(channel_parameter[freq - 760] & 0x1)) {
625 mt6626_read(0x61, &tempbuff);
626 mt6626_write(0x60, 0x330F);
627 mt6626_write(0x61, 1);
628 mt6626_write(0x6e, 0x0);
629 mt6626_write(0x6e, 0x0);
630 mt6626_write(0x6e, 0x0);
631 mt6626_write(0x6e, 0x0);
632 mt6626_write(0x60, 0x0);
633 mt6626_write(0x60, 0x4000);
634 mt6626_write(0x60, 0x0);
635 mt6626_write(0x60, 0x3000);
636 mt6626_write(0x60, 0x3001);
638 mt6626_write(0x60, 0x3003);
639 mt6626_write(0x60, 0x3007);
640 mt6626_write(0x60, 0x300f);
641 mt6626_write(0x61, tempbuff | 0x3);
642 mt6626_write(0x61, tempbuff | 0x2);
643 mt6626_write(0x6A, 0x20);
644 mt6626_write(0x6B, 0x20);
656 mt6626_writeFA(&dataRead, (channel_parameter[freq - 760]));
657 mt6626_write(FM_CHANNEL_SET, (dataRead&0xFC00) | CHAN);
661 if (mt6626_WaitSTCDone(5000, 15)) {
663 WCN_DBG(FM_ALT | CHIP, "set freq failed\n");
666 WCN_DBG(FM_WAR | CHIP, "set freq retry, cnt=%d\n", cnt);
671 mt6626_ClearSTCDone();//clear status flag
673 WCN_DBG(FM_DBG | CHIP, "set freq to %d ok\n", freq);
679 * pFreq: IN/OUT parm, IN start freq/OUT seek valid freq
680 * return fm_true:seek success; fm_false:seek failed
682 static fm_bool mt6626_Seek(fm_u16 min_freq, fm_u16 max_freq, fm_u16 *pFreq, fm_u16 seekdir, fm_u16 space)
689 mt6626_Mute(fm_true);
691 WCN_DBG(FM_DBG | CHIP, "min_freq:%d, max_freq:%d\n", min_freq, max_freq);
693 //Program seek direction
694 mt6626_read(FM_MAIN_CFG1, &dataRead);
703 WCN_DBG(FM_DBG | CHIP, "seek %s\n", seekdir ? "down" : "up");
704 //Program scan channel spacing
713 WCN_DBG(FM_DBG | CHIP, "seek space %d\n", space);
714 //enable wrap , if it is not auto scan function, 0x66[11] 0=no wrarp, 1=wrap
717 //0x66[9:0] freq upper bound
718 max_freq = (max_freq - 640) * 2;
720 dataRead |= max_freq;
721 mt6626_write(FM_MAIN_CFG1, dataRead);
722 //0x67[9:0] freq lower bound
723 mt6626_read(FM_MAIN_CFG2, &dataRead);
724 min_freq = (min_freq - 640) * 2;
726 dataRead |= min_freq;
727 mt6626_write(FM_MAIN_CFG2, dataRead);
728 //Enable STC done intr
729 mt6626_set_bits(FM_MAIN_EXTINTRMASK, FM_EXT_STC_DONE_MASK, 0xFFFE);
732 if (fm_wait_stc_done(MT6626_FM_STC_DONE_TIMEOUT) == fm_false) {
733 WCN_DBG(FM_ALT | CHIP, "seek, get stc done failed\n");
734 mt6626_set_bits(FM_MAIN_INTR, 0x0001, 0xFFFF);
739 //Disable STC done intr
740 mt6626_set_bits(FM_MAIN_EXTINTRMASK, 0, 0xFFFE);
741 //get the result freq
742 mt6626_read(FM_MAIN_CHANDETSTAT, &dataRead);
743 mt6626_write(FM_CHANNEL_SET, (dataRead&FM_HOST_CHAN) >> 4);
744 *pFreq = 640 + ((dataRead & FM_MAIN_CHANDET_MASK) >> (FM_MAIN_CHANDET_SHIFT + 1));
745 freq_l = fm_cust_config_fetch(FM_CFG_RX_BAND_FREQ_L);
746 freq_h = fm_cust_config_fetch(FM_CFG_RX_BAND_FREQ_H);
747 *pFreq = (*pFreq > freq_h) ? freq_h : *pFreq;
748 *pFreq = (*pFreq < freq_l) ? freq_l : *pFreq;
749 fm_cb_op->cur_freq_set(*pFreq);
750 WCN_DBG(FM_NTC | CHIP, "seek, result freq:%d\n", *pFreq);
751 mt6626_Mute(fm_false);
756 static fm_bool mt6626_Scan(
757 fm_u16 min_freq, fm_u16 max_freq,
764 fm_u16 tmp_reg, space_val, startfreq, offset = 0;
765 fm_u16 tmp_scanTBLsize = *ScanTBLsize;
768 if ((!pScanTBL) || (tmp_scanTBLsize == 0)) {
769 WCN_DBG(FM_ALT | CHIP, "scan, failed:invalid scan table\n");
773 WCN_DBG(FM_DBG | CHIP, "scan 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);
775 if (tmp_scanTBLsize > MT6626_SCANTBL_SIZE) {
776 tmp_scanTBLsize = MT6626_SCANTBL_SIZE;
779 if (space == MT6626_FM_SPACE_200K) {
780 space_val = 2; //200K
781 } else if (space == MT6626_FM_SPACE_100K) {
782 space_val = 1; //100K
784 space_val = 1; //100K
788 if (scandir == MT6626_FM_SCAN_UP) {
789 startfreq = min_freq - space_val;
791 startfreq = max_freq + space_val;//max_freq compare need or not
795 mt6626_Mute(fm_true);
798 if (fm_false == mt6626_SetFreq(startfreq)) {
799 WCN_DBG(FM_ALT | CHIP, "scan, failed set freq\n");
805 //set space(100k/200k)and band(min_freq~max_freq) and up/down and disable wrap
806 mt6626_read(FM_MAIN_CFG2, &dataRead);
807 mt6626_write(FM_MAIN_CFG2, (dataRead&0xFC00) | ((min_freq - 640) << 1));//set space(100k/200k)and band(875~1080)and up/down
808 mt6626_read(FM_MAIN_CFG1, &dataRead);
809 mt6626_write(FM_MAIN_CFG1, (dataRead&0x8800) | (scandir << 10) | (1 << (12 + space)) | ((max_freq - 640) << 1));//set space(100k/200k)and band(875~1080)and up/down
810 mt6626_read(FM_MAIN_CFG1, &dataRead);
811 mt6626_write(FM_MAIN_CFG1, dataRead&0xF7FF); //disable wrap , if it is auto scan function
813 //Enable STC done intr
814 mt6626_set_bits(FM_MAIN_EXTINTRMASK, FM_EXT_STC_DONE_MASK, 0xFFFE);
818 if (fm_wait_stc_done(MT6626_FM_STC_DONE_TIMEOUT) == fm_false) {
819 WCN_DBG(FM_ALT | CHIP, "scan, get stc done failed\n");
820 mt6626_set_bits(FM_MAIN_INTR, 0x0001, 0xFFFF);
823 //get the valid freq after scan
824 mt6626_read(FM_MAIN_CHANDETSTAT, &tmp_reg);
825 tmp_reg = 640 + ((tmp_reg & FM_MAIN_CHANDET_MASK) >> (FM_MAIN_CHANDET_SHIFT + 1));
827 WCN_DBG(FM_DBG | CHIP, "scan, failed freq:%d\n", *pFreq);
831 //Disable STC done intr
832 mt6626_set_bits(FM_MAIN_EXTINTRMASK, 0, 0xFFFE);
835 WCN_DBG(FM_DBG | CHIP, "mt6626_Scan tbl:");
837 for (offset = 0; offset < tmp_scanTBLsize; offset++) {
838 mt6626_read(FM_RDS_DATA_REG, &tmp_reg);
839 *(pScanTBL + offset) = tmp_reg;
842 *ScanTBLsize = tmp_scanTBLsize;
844 //get the valid freq after scan
845 mt6626_read(FM_MAIN_CHANDETSTAT, &tmp_reg);
846 tmp_reg = 640 + ((tmp_reg & FM_MAIN_CHANDET_MASK) >> (FM_MAIN_CHANDET_SHIFT + 1));
848 WCN_DBG(FM_DBG | CHIP, "scan, after scan freq:%d\n", *pFreq);
849 mt6626_Mute(fm_false);
855 * mt6626_GetCurRSSI - get current freq's RSSI value
857 * If RS>511, then RSSI(dBm)= (RS-1024)/16*6
858 * else RSSI(dBm)= RS/16*6
860 static fm_s32 mt6626_GetCurRSSI(fm_s32 *pRSSI)
864 mt6626_read(FM_RSSI_IND, &tmp_reg);
865 tmp_reg = tmp_reg & 0x03ff;
868 *pRSSI = (tmp_reg > 511) ? (((tmp_reg - 1024) * 6) >> 4) : ((tmp_reg * 6) >> 4);
869 WCN_DBG(FM_DBG | CHIP, "rssi:%d, dBm:%d\n", tmp_reg, *pRSSI);
871 WCN_DBG(FM_ERR | CHIP, "get rssi para error\n");
878 static fm_s32 mt6626_SetVol(fm_u8 vol)
880 #define MT6626_VOL_MAX 0x2B // 43 volume(0-15)
882 fm_u8 tmp_vol = vol & 0x3f;
885 mt6626_read(0x60, &tmp);
886 mt6626_write(0x60, tmp&0xFFF7); //0x60 D3=0
889 if (tmp_vol > MT6626_VOL_MAX)
890 tmp_vol = MT6626_VOL_MAX;
892 ret = mt6626_set_bits(0x9C, (tmp_vol << 8), 0xC0FF);
895 WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", tmp_vol);
898 WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", tmp_vol);
901 mt6626_write(0x60, tmp); //0x60 D3=1
905 static fm_s32 mt6626_GetVol(fm_u8 *pVol)
913 mt6626_read(0x60, &tmp);
914 mt6626_write(0x60, tmp&0xFFF7); //0x60 D3=0
916 ret = mt6626_read(0x9C, &tmp_reg);
920 WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n");
923 *pVol = (tmp_reg >> 8) & 0x3f;
924 WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol);
927 mt6626_write(0x60, tmp); //0x60 D3=1
931 static fm_s32 mt6626_dump_reg(void)
936 static fm_bool mt6626_GetMonoStereo(fm_u16 *pMonoStereo)
938 #define FM_BF_STEREO 0x1000
942 mt6626_read(FM_RSSI_IND, &TmpReg);
943 *pMonoStereo = (TmpReg & FM_BF_STEREO) >> 12;
945 WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n");
949 WCN_DBG(FM_DBG | CHIP, "MonoStero:0x%04x\n", *pMonoStereo);
953 static fm_s32 mt6626_SetMonoStereo(fm_s32 MonoStereo)
956 #define FM_FORCE_MS 0x0008
958 WCN_DBG(FM_DBG | CHIP, "set to %s\n", MonoStereo ? "mono" : "auto");
960 mt6626_write(0x60, 0x3007);
963 ret = mt6626_set_bits(0x75, FM_FORCE_MS, ~FM_FORCE_MS);
965 ret = mt6626_set_bits(0x75, 0x0000, ~FM_FORCE_MS);
971 static fm_s32 mt6626_GetCapArray(fm_s32 *ca)
977 mt6626_read(0x60, &tmp);
978 mt6626_write(0x60, tmp&0xFFF7); //0x60 D3=0
980 mt6626_read(0x25, &dataRead);
983 mt6626_write(0x60, tmp); //0x60 D3=1
989 * mt6626_GetCurPamd - get current freq's PAMD value
991 * If PA>511 then PAMD(dB)= (PA-1024)/16*6,
992 * else PAMD(dB)=PA/16*6
994 static fm_bool mt6626_GetCurPamd(fm_u16 *pPamdLevl)
999 if (mt6626_read(FM_ADDR_PAMD, &tmp_reg))
1003 dBvalue = (tmp_reg > 511) ? ((1024 - tmp_reg) * 6 / 16) : 0;
1005 *pPamdLevl = dBvalue;
1009 static fm_s32 mt6626_ScanStop(void)
1011 return fm_force_active_event(FLAG_SCAN);
1014 static fm_s32 mt6626_SeekStop(void)
1016 return fm_force_active_event(FLAG_SEEK);
1020 * mt6626_I2s_Setting - set the I2S state on MT6626
1021 * @onoff - I2S on/off
1022 * @mode - I2S mode: Master or Slave
1024 * Return:0, if success; error code, if failed
1026 static fm_s32 mt6626_I2s_Setting(fm_s32 onoff, fm_s32 mode, fm_s32 sample)
1028 fm_u16 tmp_state = 0;
1029 fm_u16 tmp_mode = 0;
1030 fm_u16 tmp_sample = 0;
1033 if (onoff == MT6626_I2S_ON) {
1034 tmp_state = 0x0080; //I2S Frequency tracking on, 0x61 D7=1
1035 } else if (onoff == MT6626_I2S_OFF) {
1036 tmp_state = 0x0000; //I2S Frequency tracking off, 0x61 D7=0
1038 WCN_DBG(FM_ERR | CHIP, "%s():[onoff=%d]\n", __func__, onoff);
1043 if (mode == MT6626_I2S_MASTER) {
1044 tmp_mode = 0x03; //6620 as I2S master
1045 } else if (mode == MT6626_I2S_SLAVE) {
1046 tmp_mode = 0x0B; //6620 as I2S slave
1048 WCN_DBG(FM_ERR | CHIP, "%s():[mode=%d]\n", __func__, mode);
1053 if (sample == MT6626_I2S_32K) {
1054 tmp_sample = 0x0000; //6620 I2S 32KHz sample rate
1055 } else if (sample == MT6626_I2S_44K) {
1056 tmp_sample = 0x0800; //6620 I2S 44.1KHz sample rate
1057 } else if (sample == MT6626_I2S_48K) {
1058 tmp_sample = 0x1000; //6620 I2S 48KHz sample rate
1060 WCN_DBG(FM_ERR | CHIP, "%s():[sample=%d]\n", __func__, sample);
1065 if ((ret = mt6626_set_bits(0x5F, tmp_sample, 0xE7FF)))
1068 if ((ret = mt6626_write(0x9B, tmp_mode)))
1071 if ((ret = mt6626_set_bits(0x61, tmp_state, 0xFF7F)))
1074 WCN_DBG(FM_NTC | CHIP, "[onoff=%s][mode=%s][sample=%d](0)33KHz,(1)44.1KHz,(2)48KHz\n",
1075 (onoff == MT6626_I2S_ON) ? "On" : "Off",
1076 (mode == MT6626_I2S_MASTER) ? "Master" : "Slave",
1082 static fm_bool mt6626_em_test(fm_u16 group_idx, fm_u16 item_idx, fm_u32 item_value)
1087 static fm_s32 fm_low_power_wa_default(fm_s32 fmon)
1092 fm_s32 fm_low_ops_register(struct fm_lowlevel_ops *ops)
1098 FMR_ASSERT(ops->cb.cur_freq_get);
1099 FMR_ASSERT(ops->cb.cur_freq_set);
1100 fm_cb_op = &ops->cb;
1102 //ops->bi.low_pwr_wa = mt6626_low_pwr_wa;
1103 ops->bi.low_pwr_wa = fm_low_power_wa_default;
1104 ops->bi.pwron = mt6626_pwron;
1105 ops->bi.pwroff = mt6626_pwroff;
1106 ops->bi.msdelay = Delayms;
1107 ops->bi.usdelay = Delayus;
1108 ops->bi.read = mt6626_read;
1109 ops->bi.write = mt6626_write;
1110 ops->bi.setbits = mt6626_set_bits;
1111 ops->bi.chipid_get = mt6626_get_chipid;
1112 ops->bi.mute = mt6626_Mute;
1113 ops->bi.rampdown = mt6626_RampDown;
1114 ops->bi.pwrupseq = mt6626_PowerUp;
1115 ops->bi.pwrdownseq = mt6626_PowerDown;
1116 ops->bi.setfreq = mt6626_SetFreq;
1117 ops->bi.seek = mt6626_Seek;
1118 ops->bi.seekstop = mt6626_SeekStop;
1119 ops->bi.scan = mt6626_Scan;
1120 ops->bi.scanstop = mt6626_ScanStop;
1121 ops->bi.rssiget = mt6626_GetCurRSSI;
1122 ops->bi.volset = mt6626_SetVol;
1123 ops->bi.volget = mt6626_GetVol;
1124 ops->bi.dumpreg = mt6626_dump_reg;
1125 ops->bi.msget = mt6626_GetMonoStereo;
1126 ops->bi.msset = mt6626_SetMonoStereo;
1127 ops->bi.pamdget = mt6626_GetCurPamd;
1128 ops->bi.em = mt6626_em_test;
1129 ops->bi.anaswitch = mt6626_SetAntennaType;
1130 ops->bi.anaget = mt6626_GetAntennaType;
1131 ops->bi.caparray_get = mt6626_GetCapArray;
1132 ops->bi.i2s_set = mt6626_I2s_Setting;
1137 fm_s32 fm_low_ops_unregister(struct fm_lowlevel_ops *ops)
1144 fm_memset(&ops->bi, 0, sizeof(struct fm_basic_interface));