MT6620: add the new driver JB2 V1.0
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_fm / mt6626 / pub / mt6626_fm_lib.c
1 #include <linux/semaphore.h>
2 #include <linux/delay.h>
3 #include <linux/slab.h>
4
5 #include "fm_typedef.h"
6 #include "fm_dbg.h"
7 #include "fm_err.h"
8 #include "fm_interface.h"
9 #include "fm_stdlib.h"
10 #include "fm_patch.h"
11 #include "fm_config.h"
12
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"
19
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"
24
25 extern void fm_low_power_wa(int fmon);
26 extern void mt66x6_poweron(int idx);
27 extern void mt66x6_poweroff(int idx);
28
29 static struct fm_callback *fm_cb_op;
30
31 /* mt6626 FM Receiver Power Up Sequence*/
32 static const struct ctrl_word_operation PowerOnSetting[] = {
33     //@Wholechip FM Power Up: FM Digital Clock enable
34     {0x60, 0x0, 0x3000},
35     {0x60, 0x0, 0x3001},
36     {MSDELAY, 0x0, 0x0003},//Delay 3ms
37     {0x60, 0x0, 0x3003},
38     {0x60, 0x0, 0x3007},
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
44 #else
45     {0x61, 0xFF73, 0x0080},//no low power mode, I2S, long antenna
46 #endif
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
52 #else
53 #ifdef FM_PowerOn_with_ShortAntenna
54     {0x61, 0xFF63, 0x0010},//no low power mode, analog line in, short antenna
55 #else
56     {0x61, 0xFF63, 0x0000},//no low power mode, analog line in, long antenna
57 #endif
58 #endif
59     {HW_VER, 0x0062, 0x0000},//read the HW version
60
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},
65     {0x90, 0x0, 0x0040},
66     {0x90, 0x0, 0x0000},
67
68     //@Wholechip FM Power Up: FM Digital Init: fm_rgf_maincon
69     {0x6A, 0x0, 0x0020},
70     {0x6B, 0x0, 0x0020},
71     {0x60, 0x0, 0x300F},
72     {0x61, 0xFFFF, 0x0002},
73     {0x61, 0xFFFE, 0x0000},
74     {POLL_P, 0x64, 0x2}
75 };
76 #define POWER_ON_COMMAND_COUNT (sizeof(PowerOnSetting)/sizeof(PowerOnSetting[0]))
77
78 static int Chip_Version = mt6626_E1;
79
80
81 static fm_s32 mt6626_pwron(fm_s32 data)
82 {
83     mt66x6_poweron(MT66x6_FM);
84     return 0;
85 }
86
87
88 static fm_s32 mt6626_pwroff(fm_s32 data)
89 {
90     mt66x6_poweroff(MT66x6_FM);
91     return 0;
92 }
93
94 static fm_s32 Delayms(fm_u32 data)
95 {
96     WCN_DBG(FM_DBG | CHIP, "delay %dms\n", data);
97     msleep(data);
98     return 0;
99 }
100
101 static fm_s32 Delayus(fm_u32 data)
102 {
103     WCN_DBG(FM_DBG | CHIP, "delay %dus\n", data);
104     udelay(data);
105     return 0;
106 }
107
108 static fm_s32 mt6626_read(fm_u8 addr, fm_u16 *val)
109 {
110     fm_s32 ret = 0;
111
112     ret = fm_ctrl_rx(addr, val);
113
114     if (ret) {
115         WCN_DBG(FM_ALT | CHIP, "rd 0x%02x err\n", addr);
116         return ret;
117     }
118
119     WCN_DBG(FM_DBG | CHIP, "rd 0x%02x 0x%04x\n", addr, *val);
120     return ret;
121 }
122
123 static fm_s32 mt6626_write(fm_u8 addr, fm_u16 val)
124 {
125     fm_s32 ret = 0;
126
127     ret = fm_ctrl_tx(addr, val);
128
129     if (ret) {
130         WCN_DBG(FM_ALT | CHIP, "wr 0x%02x err\n", addr);
131         return ret;
132     }
133
134     WCN_DBG(FM_DBG | CHIP, "wr 0x%02x 0x%04x\n", addr, val);
135     return ret;
136 }
137
138 static fm_s32 mt6626_write1(fm_u8 addr, fm_u16 val)
139 {
140     return fm_ctrl_tx(addr, val);
141 }
142
143 static fm_s32 mt6626_set_bits(fm_u8 addr, fm_u16 bits, fm_u16 mask)
144 {
145     fm_s32 ret = 0;
146     fm_u16 val;
147
148     ret = mt6626_read(addr, &val);
149
150     if (ret)
151         return ret;
152
153     val = ((val & (mask)) | bits);
154     ret = mt6626_write(addr, val);
155
156     return ret;
157 }
158
159 static fm_u16 mt6626_get_chipid(void)
160 {
161     return 0x6626;
162 }
163
164 static void mt6626_TUNE_ON(void)
165 {
166     fm_u16 dataRead;
167
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);
172 }
173
174 static void mt6626_SEEK_ON(void)
175 {
176     fm_u16 dataRead;
177
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);
182 }
183
184 static void mt6626_SCAN_ON(void)
185 {
186     fm_u16 dataRead;
187
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);
192 }
193
194 /*  MT6628_SetAntennaType - set Antenna type
195  *  @type - 1,Short Antenna;  0, Long Antenna
196  */
197 static fm_s32 mt6626_SetAntennaType(fm_s32 type)
198 {
199     fm_u16 dataRead;
200
201     WCN_DBG(FM_DBG | CHIP, "set ana to %s\n", type ? "short" : "long");
202     mt6626_read(FM_MAIN_CG2_CTRL, &dataRead);
203
204     if (type) {
205         dataRead |= ANTENNA_TYPE;
206     } else {
207         dataRead &= (~ANTENNA_TYPE);
208     }
209
210     mt6626_write(FM_MAIN_CG2_CTRL, dataRead);
211
212     return 0;
213 }
214
215 static fm_s32 mt6626_GetAntennaType(void)
216 {
217     fm_u16 dataRead;
218
219     mt6626_read(FM_MAIN_CG2_CTRL, &dataRead);
220     WCN_DBG(FM_DBG | CHIP, "get ana type: %s\n", (dataRead&ANTENNA_TYPE) ? "short" : "long");
221
222     if (dataRead&ANTENNA_TYPE)
223         return FM_SHORT_ANA; //short antenna
224     else
225         return FM_LONG_ANA; //long antenna
226 }
227
228 static fm_s32 mt6626_writeFA(fm_u16 *buff, fm_u8 fa)
229 {
230     fm_u8 i = 0;
231
232     for (i = 0; i < 3; i++) {
233         if ((fa >> i)& 0x1)
234             *buff |= (1 << (12 + i));
235         else
236             *buff &= ~(1 << (12 + i));
237     }
238
239     return 0;
240 }
241
242 static fm_s32 mt6626_Mute(fm_bool mute)
243 {
244     fm_u16 dataRead;
245
246     WCN_DBG(FM_DBG | CHIP, "set %s\n", mute ? "mute" : "unmute");
247     mt6626_read(FM_MAIN_CTRL, &dataRead);
248
249     if (mute == 1) {
250         mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFDF) | 0x0020);
251     } else {
252         mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFDF));
253     }
254
255     return 0;
256 }
257
258 /*
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
263  */
264 static fm_s32 mt6626_WaitSTCDone(fm_u32 waittime, fm_u32 interval)
265 {
266     fm_u16 dataRead;
267     fm_s32 cnt;
268
269     if (interval) {
270         cnt = waittime / interval;
271     } else {
272         cnt = 0;
273     }
274
275     do {
276         if (cnt-- < 0) {
277             return -1; //wait for STC done failed
278         }
279
280         Delayms(interval);
281         mt6626_read(FM_MAIN_INTR, &dataRead);
282     } while ((dataRead&FM_INTR_STC_DONE) == 0);
283
284     return 0;
285 }
286
287 static fm_s32 mt6626_ClearSTCDone(void)
288 {
289     fm_u16 dataRead;
290
291     mt6626_read(FM_MAIN_INTR, &dataRead);
292     mt6626_write(FM_MAIN_INTR, dataRead | FM_INTR_STC_DONE);//clear status flag
293     return 0;
294 }
295
296 static fm_s32 mt6626_RampDown(void)
297 {
298     fm_u16 dataRead;
299
300     WCN_DBG(FM_DBG | CHIP, "ramp down\n");
301     //Clear DSP state
302     mt6626_read(FM_MAIN_CTRL, &dataRead);
303     mt6626_write(FM_MAIN_CTRL, (dataRead&0xFFF0)); //clear rgf_tune/seek/scan/dsp_init
304
305     //Set DSP ramp down state
306     mt6626_read(FM_MAIN_CTRL, &dataRead);
307     mt6626_write(FM_MAIN_CTRL, (dataRead | RAMP_DOWN));
308
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");
312         return -1;
313     }
314
315     //Clear DSP ramp down state
316     mt6626_read(FM_MAIN_CTRL, &dataRead);
317     mt6626_write(FM_MAIN_CTRL, (dataRead&(~RAMP_DOWN)));
318
319     mt6626_ClearSTCDone();
320     return 0;
321 }
322
323 /*
324 *  mt6626_DspPatch - DSP download procedure
325 *  @img - source dsp bin code
326 *  @type - rom/patch/coefficient/hw_coefficient
327 *
328 */
329 static fm_s32 mt6626_DspPatch(const fm_u16 *img, enum IMG_TYPE type)
330 {
331     fm_u32 ctrl_code = 0;
332     fm_u16 data_len = 0;        // in words
333     fm_u16 i;
334
335     FMR_ASSERT(img);
336
337     WCN_DBG(FM_DBG | CHIP, "down load DSP patch %d (1-rom, 2-patch, 3-coe, 4-hwcoe)\n", type);
338
339     switch (type) {
340     case IMG_ROM:                       //rom code
341     case IMG_PATCH:             //patch
342         ctrl_code = 0x10;
343         break;
344     case IMG_COEFFICIENT:       //coeff
345         ctrl_code = 0xe;
346         break;
347     case IMG_HW_COEFFICIENT:    //HW coeff
348         ctrl_code = 0xd;
349         break;
350     default:
351         break;
352     }
353
354     data_len = img[1] - img[0] + 1;
355     WCN_DBG(FM_DBG | CHIP, "patch len: %d\n", data_len);
356
357     if (!(data_len > 0)) {
358         ; //error
359         return -FM_EPARA;
360     }
361
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
366
367     switch (type) {
368     case IMG_ROM:
369     case IMG_PATCH:
370     case IMG_HW_COEFFICIENT:
371         WCN_DBG(FM_DBG | CHIP, "rom/patch/hw_coefficient downloading......\n");
372
373         for (i = 0; i < data_len; i++) {
374             mt6626_write1(FM_DSP_PATCH_DATA, img[2+i]);
375         }
376
377         break;
378     case IMG_COEFFICIENT:
379         WCN_DBG(FM_DBG | CHIP, "coefficient downloading......\n");
380
381         if (MT6626_DEEMPHASIS_50us) {
382             for (i = 0; i < data_len; i++) {
383                 if (i == 86) {
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);
399                     i += 12;
400                 } else if (i == 505) {
401                     mt6626_write1(FM_DSP_PATCH_DATA, fm_cust_config_fetch(FM_CFG_RX_RSSI_TH_SHORT));
402                 } else {
403                     mt6626_write1(FM_DSP_PATCH_DATA, img[2+i]);
404                 }
405             }
406         } else {
407             for (i = 0; i < data_len; i++) {
408                 if (i == 86) {
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));
412                 } else {
413                     mt6626_write1(FM_DSP_PATCH_DATA, img[2+i]);
414                 }
415             }
416         }
417
418         break;
419     default:
420         break;
421     }
422
423     WCN_DBG(FM_DBG | CHIP, "down load DSP patch %d ok\n", type);
424     return 0;
425 }
426
427 static fm_s32 mt6626_PowerUp(fm_u16 *chip_id, fm_u16 *device_id)
428 {
429     fm_s32 ret = 0;
430     fm_s32 i;
431     fm_u16 tmp_reg, cnt = 0;
432
433     const fm_u16 *bin_patch = NULL;
434     const fm_u16 *bin_coeff = NULL;
435
436     FMR_ASSERT(chip_id);
437     FMR_ASSERT(device_id);
438
439     WCN_DBG(FM_DBG | CHIP, "pwr on seq\n");
440
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:
445
446             switch (PowerOnSetting[i].or) {
447             case DSP_PATH:  //DSP path download
448                 mt6626_DspPatch(bin_patch, IMG_PATCH);
449                 break;
450             case DSP_COEFF:  //DSP coefficient download
451                 mt6626_DspPatch(bin_coeff, IMG_COEFFICIENT);
452                 break;
453             case DSP_HW_COEFF:  //DSP HW coefficient download
454                 mt6626_DspPatch(bin_hw_coeff, IMG_HW_COEFFICIENT);
455                 break;
456             default:
457                 break;
458             }
459
460             break;
461         case FM_PUS_POLL_P:
462             cnt = 0;
463
464             do {
465                 mt6626_read((fm_u8)PowerOnSetting[i].and, &tmp_reg);
466                 tmp_reg &= PowerOnSetting[i].or;
467
468                 if (tmp_reg == 0) {
469                     Delayms(10);
470                     cnt++;
471                 }
472             } while ((tmp_reg == 0) && (cnt < (MT6626_MAX_COUNT << 1)));
473
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);
476                 return -FM_EPARA;
477             }
478
479             break;
480         case FM_PUS_POLL_N:
481             cnt = 0;
482
483             do {
484                 mt6626_read((fm_u8)PowerOnSetting[i].and, &tmp_reg);
485                 tmp_reg &= PowerOnSetting[i].or;
486
487                 if (tmp_reg != 0) {
488                     Delayms(10);
489                     cnt++;
490                 }
491             } while ((tmp_reg != 0) && (cnt < MT6626_MAX_COUNT));
492
493             if (cnt == MT6626_MAX_COUNT) {
494                 WCN_DBG(FM_ALT | CHIP, "polling status Negative failed:0x%02X\n", (fm_u8)PowerOnSetting[i].and);
495                 return -FM_EPARA;
496             }
497
498             break;
499         case FM_PUS_USDELAY:
500             Delayus(PowerOnSetting[i].or);
501             break;
502         case FM_PUS_MSDELAY:
503             Delayms(PowerOnSetting[i].or);
504             break;
505         case FM_PUS_HW_VER:
506
507             switch (PowerOnSetting[i].and) {
508             case 0x99:
509                 mt6626_read(0x99, &tmp_reg);
510
511                 switch (tmp_reg) {
512                 case 0x0:
513                     Chip_Version = mt6626_E1;
514                     bin_patch = bin_patch_E1;
515                     bin_coeff = bin_coeff_E1;
516                     break;
517                 case 0x8A01:
518                 default:
519                     Chip_Version = mt6626_E2;
520                     bin_patch = bin_patch_E2;
521                     bin_coeff = bin_coeff_E2;
522                     break;
523                 }
524
525                 break;
526             case 0x62:
527                 mt6626_read((fm_u8)PowerOnSetting[i].and, &tmp_reg);
528                 //record chip id & device id
529                 *chip_id = tmp_reg;
530                 *device_id = tmp_reg;
531                 WCN_DBG(FM_NTC | CHIP, "chip_id:0x%04x\n", tmp_reg);
532                 break;
533             case 0x1C:
534                 mt6626_read((fm_u8)PowerOnSetting[i].and, &tmp_reg);
535
536                 if (PowerOnSetting[i].or) {
537                     mt6626_write(PowerOnSetting[i].and, (tmp_reg | 0x8000));
538                 } else {
539                     mt6626_write(PowerOnSetting[i].and, (tmp_reg&0x7FFF));
540                 }
541
542                 break;
543             default:
544                 break;
545             }
546
547             break;
548         default:
549
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);
553                     return -FM_EPARA;
554                 }
555
556                 tmp_reg &= PowerOnSetting[i].and;
557                 tmp_reg |= PowerOnSetting[i].or;
558             } else {
559                 tmp_reg = PowerOnSetting[i].or;
560             }
561
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);
564                 return -FM_EPARA;
565             }
566
567             break;
568         }
569     }
570
571     WCN_DBG(FM_DBG | CHIP, "pwr on seq done\n");
572     return ret;
573 }
574
575 static fm_s32 mt6626_PowerDown(void)
576 {
577     fm_s32 ret = 0;
578     fm_s16 i;
579     fm_u16 dataRead;
580
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.
584      */
585     WCN_DBG(FM_DBG | CHIP, "pwr down seq\n");
586     mt6626_read(FM_MAIN_INTR, &dataRead);
587
588     if (dataRead & 0x1) {
589         mt6626_write(FM_MAIN_INTR, dataRead);//clear status flag
590     }
591
592     mt6626_RampDown();
593
594     mt6626_write(0x60, 0x330F);
595     mt6626_write(FM_MAIN_CG2_CTRL, 1);
596
597     for (i = 0; i < 4; i++) {
598         mt6626_read(0x6E, &dataRead);
599         mt6626_write(0x6E, (dataRead&0xFFF8));
600     }
601
602     mt6626_write(FM_MAIN_CG1_CTRL, 0);
603     mt6626_write(FM_MAIN_CG1_CTRL, 0x4000);
604     mt6626_write(FM_MAIN_CG1_CTRL, 0);
605
606     return ret;
607 }
608
609 static fm_bool mt6626_SetFreq(fm_u16 freq)
610 {
611     fm_u32 CHAN = 0x0000;
612     fm_u16 dataRead, cnt = 0, tempbuff = 0;
613
614 Rampdown_again:
615     mt6626_RampDown();
616
617     fm_cb_op->cur_freq_set(freq);
618     CHAN = (freq - 640) << 1;
619     mt6626_read(FM_CHANNEL_SET, &dataRead);
620
621     switch (Chip_Version) {
622     case mt6626_E1:
623
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);
637             Delayms(3);
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);
645             Delayms(200);
646         }
647
648         break;
649     case mt6626_E2:
650         break;
651     default:
652         break;
653
654     }
655
656     mt6626_writeFA(&dataRead, (channel_parameter[freq - 760]));
657     mt6626_write(FM_CHANNEL_SET, (dataRead&0xFC00) | CHAN);
658
659     mt6626_TUNE_ON();
660
661     if (mt6626_WaitSTCDone(5000, 15)) {
662         if (cnt++ > 100) {
663             WCN_DBG(FM_ALT | CHIP, "set freq failed\n");
664             return FALSE;
665         } else {
666             WCN_DBG(FM_WAR | CHIP, "set freq retry, cnt=%d\n", cnt);
667             goto Rampdown_again;
668         }
669     }
670
671     mt6626_ClearSTCDone();//clear status flag
672
673     WCN_DBG(FM_DBG | CHIP, "set freq to %d ok\n", freq);
674     return TRUE;
675 }
676
677 /*
678 * mt6626_Seek
679 * pFreq: IN/OUT parm, IN start freq/OUT seek valid freq
680 * return fm_true:seek success; fm_false:seek failed
681 */
682 static fm_bool mt6626_Seek(fm_u16 min_freq, fm_u16 max_freq, fm_u16 *pFreq, fm_u16 seekdir, fm_u16 space)
683 {
684     fm_u16 dataRead;
685     fm_u16 freq_l;
686     fm_u16 freq_h;
687
688     mt6626_RampDown();
689     mt6626_Mute(fm_true);
690
691     WCN_DBG(FM_DBG | CHIP, "min_freq:%d, max_freq:%d\n", min_freq, max_freq);
692
693     //Program seek direction
694     mt6626_read(FM_MAIN_CFG1, &dataRead);
695     dataRead &= 0xFBFF;
696
697     if (seekdir == 0) {
698         dataRead |= 0x0000;
699     } else {
700         dataRead |= 0x0400;
701     }
702
703     WCN_DBG(FM_DBG | CHIP, "seek %s\n", seekdir ? "down" : "up");
704     //Program scan channel spacing
705     dataRead &= 0x8FFF;
706
707     if (space == 4) {
708         dataRead |= 0x4000;
709     } else {
710         dataRead |= 0x2000;
711     }
712
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
715     dataRead &= 0xF7FF;
716     dataRead |= 0x0800;
717     //0x66[9:0] freq upper bound
718     max_freq = (max_freq - 640) * 2;
719     dataRead &= 0xFC00;
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;
725     dataRead &= 0xFC00;
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);
730     mt6626_SEEK_ON();
731
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);
735         mt6626_RampDown();
736         return fm_false;
737     }
738
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);
752
753     return fm_true;
754 }
755
756 static fm_bool mt6626_Scan(
757     fm_u16 min_freq, fm_u16 max_freq,
758     fm_u16 *pFreq,
759     fm_u16 *pScanTBL,
760     fm_u16 *ScanTBLsize,
761     fm_u16 scandir,
762     fm_u16 space)
763 {
764     fm_u16 tmp_reg, space_val, startfreq, offset = 0;
765     fm_u16 tmp_scanTBLsize = *ScanTBLsize;
766     fm_u16 dataRead;
767
768     if ((!pScanTBL) || (tmp_scanTBLsize == 0)) {
769         WCN_DBG(FM_ALT | CHIP, "scan, failed:invalid scan table\n");
770         return fm_false;
771     }
772
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);
774
775     if (tmp_scanTBLsize > MT6626_SCANTBL_SIZE) {
776         tmp_scanTBLsize = MT6626_SCANTBL_SIZE;
777     }
778
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
783     } else {
784         space_val = 1;  //100K
785     }
786
787     //scan up
788     if (scandir == MT6626_FM_SCAN_UP) {
789         startfreq = min_freq - space_val;
790     } else {
791         startfreq = max_freq + space_val;//max_freq compare need or not
792     }
793
794     mt6626_RampDown();
795     mt6626_Mute(fm_true);
796
797     //set freq
798     if (fm_false == mt6626_SetFreq(startfreq)) {
799         WCN_DBG(FM_ALT | CHIP, "scan, failed set freq\n");
800         return fm_false;
801     }
802
803     mt6626_RampDown();
804
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
812
813     //Enable STC done intr
814     mt6626_set_bits(FM_MAIN_EXTINTRMASK, FM_EXT_STC_DONE_MASK, 0xFFFE);
815     //scan on
816     mt6626_SCAN_ON();
817
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);
821         mt6626_RampDown();
822
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));
826         *pFreq = tmp_reg;
827         WCN_DBG(FM_DBG | CHIP, "scan, failed freq:%d\n", *pFreq);
828         return fm_false;
829     }
830
831     //Disable STC done intr
832     mt6626_set_bits(FM_MAIN_EXTINTRMASK, 0, 0xFFFE);
833
834     //get scan Table
835     WCN_DBG(FM_DBG | CHIP, "mt6626_Scan tbl:");
836
837     for (offset = 0; offset < tmp_scanTBLsize; offset++) {
838         mt6626_read(FM_RDS_DATA_REG, &tmp_reg);
839         *(pScanTBL + offset) = tmp_reg;
840     }
841
842     *ScanTBLsize = tmp_scanTBLsize;
843
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));
847     *pFreq = tmp_reg;
848     WCN_DBG(FM_DBG | CHIP, "scan, after scan freq:%d\n", *pFreq);
849     mt6626_Mute(fm_false);
850
851     return fm_true;
852 }
853
854 /*
855  * mt6626_GetCurRSSI - get current freq's RSSI value
856  * RS=RSSI
857  * If RS>511, then RSSI(dBm)= (RS-1024)/16*6
858  *                                 else RSSI(dBm)= RS/16*6
859  */
860 static fm_s32 mt6626_GetCurRSSI(fm_s32 *pRSSI)
861 {
862     fm_u16 tmp_reg;
863
864     mt6626_read(FM_RSSI_IND, &tmp_reg);
865     tmp_reg = tmp_reg & 0x03ff;
866
867     if (pRSSI) {
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);
870     } else {
871         WCN_DBG(FM_ERR | CHIP, "get rssi para error\n");
872         return -FM_EPARA;
873     }
874
875     return 0;
876 }
877
878 static fm_s32 mt6626_SetVol(fm_u8 vol)
879 {
880 #define MT6626_VOL_MAX   0x2B   // 43 volume(0-15)
881     int ret = 0;
882     fm_u8 tmp_vol = vol & 0x3f;
883     fm_u16 tmp = 0;
884
885     mt6626_read(0x60, &tmp);
886     mt6626_write(0x60, tmp&0xFFF7); //0x60 D3=0
887
888     tmp_vol = vol * 3;
889     if (tmp_vol > MT6626_VOL_MAX)
890         tmp_vol = MT6626_VOL_MAX;
891
892     ret = mt6626_set_bits(0x9C, (tmp_vol << 8), 0xC0FF);
893
894     if (ret) {
895         WCN_DBG(FM_ERR | CHIP, "Set vol=%d Failed\n", tmp_vol);
896         return ret;
897     } else {
898         WCN_DBG(FM_DBG | CHIP, "Set vol=%d OK\n", tmp_vol);
899     }
900
901     mt6626_write(0x60, tmp); //0x60 D3=1
902     return 0;
903 }
904
905 static fm_s32 mt6626_GetVol(fm_u8 *pVol)
906 {
907     int ret = 0;
908     fm_u16 tmp_reg;
909     fm_u16 tmp = 0;
910
911     FMR_ASSERT(pVol);
912
913     mt6626_read(0x60, &tmp);
914     mt6626_write(0x60, tmp&0xFFF7); //0x60 D3=0
915
916     ret = mt6626_read(0x9C, &tmp_reg);
917
918     if (ret) {
919         *pVol = 0;
920         WCN_DBG(FM_ERR | CHIP, "Get vol Failed\n");
921         return ret;
922     } else {
923         *pVol = (tmp_reg >> 8) & 0x3f;
924         WCN_DBG(FM_DBG | CHIP, "Get vol=%d OK\n", *pVol);
925     }
926
927     mt6626_write(0x60, tmp); //0x60 D3=1
928     return 0;
929 }
930
931 static fm_s32 mt6626_dump_reg(void)
932 {
933     return 0;
934 }
935
936 static fm_bool mt6626_GetMonoStereo(fm_u16 *pMonoStereo)
937 {
938 #define FM_BF_STEREO 0x1000
939     fm_u16 TmpReg;
940
941     if (pMonoStereo) {
942         mt6626_read(FM_RSSI_IND, &TmpReg);
943         *pMonoStereo = (TmpReg & FM_BF_STEREO) >> 12;
944     } else {
945         WCN_DBG(FM_ERR | CHIP, "MonoStero: para err\n");
946         return fm_false;
947     }
948
949     WCN_DBG(FM_DBG | CHIP, "MonoStero:0x%04x\n", *pMonoStereo);
950     return fm_true;
951 }
952
953 static fm_s32 mt6626_SetMonoStereo(fm_s32 MonoStereo)
954 {
955     fm_s32 ret = 0;
956 #define FM_FORCE_MS 0x0008
957
958     WCN_DBG(FM_DBG | CHIP, "set to %s\n", MonoStereo ? "mono" : "auto");
959
960     mt6626_write(0x60, 0x3007);
961
962     if (MonoStereo) {
963         ret = mt6626_set_bits(0x75, FM_FORCE_MS, ~FM_FORCE_MS);
964     } else {
965         ret = mt6626_set_bits(0x75, 0x0000, ~FM_FORCE_MS);
966     }
967
968     return ret;
969 }
970
971 static fm_s32 mt6626_GetCapArray(fm_s32 *ca)
972 {
973     fm_u16 dataRead;
974     fm_u16 tmp = 0;
975
976     FMR_ASSERT(ca);
977     mt6626_read(0x60, &tmp);
978     mt6626_write(0x60, tmp&0xFFF7); //0x60 D3=0
979
980     mt6626_read(0x25, &dataRead);
981     *ca = dataRead;
982
983     mt6626_write(0x60, tmp); //0x60 D3=1
984     return 0;
985 }
986
987
988 /*
989  * mt6626_GetCurPamd - get current freq's PAMD value
990  * PA=PAMD
991  * If PA>511 then PAMD(dB)=  (PA-1024)/16*6,
992  *                              else PAMD(dB)=PA/16*6
993  */
994 static fm_bool mt6626_GetCurPamd(fm_u16 *pPamdLevl)
995 {
996     fm_u16 tmp_reg;
997     fm_u16 dBvalue;
998
999     if (mt6626_read(FM_ADDR_PAMD, &tmp_reg))
1000         return fm_false;
1001
1002     tmp_reg &= 0x03FF;
1003     dBvalue = (tmp_reg > 511) ? ((1024 - tmp_reg) * 6 / 16) : 0;
1004
1005     *pPamdLevl = dBvalue;
1006     return fm_true;
1007 }
1008
1009 static fm_s32 mt6626_ScanStop(void)
1010 {
1011     return fm_force_active_event(FLAG_SCAN);
1012 }
1013
1014 static fm_s32 mt6626_SeekStop(void)
1015 {
1016     return fm_force_active_event(FLAG_SEEK);
1017 }
1018
1019 /*
1020  * mt6626_I2s_Setting - set the I2S state on MT6626
1021  * @onoff - I2S on/off
1022  * @mode - I2S mode: Master or Slave
1023  *
1024  * Return:0, if success; error code, if failed
1025  */
1026 static fm_s32 mt6626_I2s_Setting(fm_s32 onoff, fm_s32 mode, fm_s32 sample)
1027 {
1028     fm_u16 tmp_state = 0;
1029     fm_u16 tmp_mode = 0;
1030     fm_u16 tmp_sample = 0;
1031     fm_s32 ret = 0;
1032
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
1037     } else {
1038         WCN_DBG(FM_ERR | CHIP, "%s():[onoff=%d]\n", __func__, onoff);
1039         ret = -FM_EPARA;
1040         goto out;
1041     }
1042
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
1047     } else {
1048         WCN_DBG(FM_ERR | CHIP, "%s():[mode=%d]\n", __func__, mode);
1049         ret = -FM_EPARA;
1050         goto out;
1051     }
1052
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
1059     } else {
1060         WCN_DBG(FM_ERR | CHIP, "%s():[sample=%d]\n", __func__, sample);
1061         ret = -FM_EPARA;
1062         goto out;
1063     }
1064
1065     if ((ret = mt6626_set_bits(0x5F, tmp_sample, 0xE7FF)))
1066         goto out;
1067
1068     if ((ret = mt6626_write(0x9B, tmp_mode)))
1069         goto out;
1070
1071     if ((ret = mt6626_set_bits(0x61, tmp_state, 0xFF7F)))
1072         goto out;
1073
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",
1077             sample);
1078 out:
1079     return ret;
1080 }
1081
1082 static fm_bool mt6626_em_test(fm_u16 group_idx, fm_u16 item_idx, fm_u32 item_value)
1083 {
1084     return fm_true;
1085 }
1086
1087 static fm_s32 fm_low_power_wa_default(fm_s32 fmon)
1088 {
1089     return 0;
1090 }
1091
1092 fm_s32 fm_low_ops_register(struct fm_lowlevel_ops *ops)
1093 {
1094     fm_s32 ret = 0;
1095     //Basic functions.
1096
1097     FMR_ASSERT(ops);
1098     FMR_ASSERT(ops->cb.cur_freq_get);
1099     FMR_ASSERT(ops->cb.cur_freq_set);
1100     fm_cb_op = &ops->cb;
1101
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;
1133
1134     return ret;
1135 }
1136
1137 fm_s32 fm_low_ops_unregister(struct fm_lowlevel_ops *ops)
1138 {
1139     fm_s32 ret = 0;
1140     //Basic functions.
1141
1142     FMR_ASSERT(ops);
1143
1144     fm_memset(&ops->bi, 0, sizeof(struct fm_basic_interface));
1145     return ret;
1146 }
1147