MT6620: add the new driver JB2 V1.0
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_fm / mt6620 / pub / mt6620_fm_config.c
1 /* fm_config.c
2  *
3  * (C) Copyright 2011
4  * MediaTek <www.MediaTek.com>
5  * hongcheng <hongcheng.xia@MediaTek.com>
6  *
7  * FM Radio Driver
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 #include <linux/string.h>
24 #include <linux/slab.h>
25
26 #include "fm_typedef.h"
27 #include "fm_rds.h"
28 #include "fm_dbg.h"
29 #include "fm_err.h"
30 #include "fm_stdlib.h"
31 #include "fm_patch.h"
32 #include "fm_config.h"
33 //#include "fm_cust_cfg.h"
34 #include "mt6620_fm_cust_cfg.h"
35
36 fm_cust_cfg mt6620_fm_config;
37 //static fm_s32 fm_index = 0;
38
39 static fm_s32 MT6620fm_cust_config_print(fm_cust_cfg *cfg)
40 {
41  //   fm_s32 i;
42
43     WCN_DBG(FM_NTC | MAIN, "MT6620 rssi_l:\t%d\n", cfg->rx_cfg.long_ana_rssi_th);
44     WCN_DBG(FM_NTC | MAIN, "MT6620 rssi_s:\t%d\n", cfg->rx_cfg.short_ana_rssi_th);
45     WCN_DBG(FM_NTC | MAIN, "MT6620 pamd_th:\t%d\n", cfg->rx_cfg.pamd_th);
46     WCN_DBG(FM_NTC | MAIN, "MT6620 mr_th:\t%d\n", cfg->rx_cfg.mr_th);
47     WCN_DBG(FM_NTC | MAIN, "MT6620 atdc_th:\t%d\n", cfg->rx_cfg.atdc_th);
48     WCN_DBG(FM_NTC | MAIN, "MT6620 prx_th:\t%d\n", cfg->rx_cfg.prx_th);
49     WCN_DBG(FM_NTC | MAIN, "MT6620 atdev_th:\t%d\n", cfg->rx_cfg.atdev_th);
50     WCN_DBG(FM_NTC | MAIN, "MT6620 smg_th:\t%d\n", cfg->rx_cfg.smg_th);
51     WCN_DBG(FM_NTC | MAIN, "MT6620 de_emphasis:\t%d\n", cfg->rx_cfg.deemphasis);
52     WCN_DBG(FM_NTC | MAIN, "MT6620 osc_freq:\t%d\n", cfg->rx_cfg.osc_freq);
53     
54     WCN_DBG(FM_NTC | MAIN, "MT6620 scan_hole_low:\t%d\n", cfg->tx_cfg.scan_hole_low);
55     WCN_DBG(FM_NTC | MAIN, "MT6620 scan_hole_high:\t%d\n", cfg->tx_cfg.scan_hole_high);
56     WCN_DBG(FM_NTC | MAIN, "MT6620 power_level:\t%d\n", cfg->tx_cfg.power_level);
57 #if 0
58     WCN_DBG(FM_NTC | MAIN, "MT6620 rssi_l:\t0x%04x\n", cfg->rx_cfg.long_ana_rssi_th);
59     WCN_DBG(FM_NTC | MAIN, "MT6620 rssi_s:\t0x%04x\n", cfg->rx_cfg.short_ana_rssi_th);
60     WCN_DBG(FM_NTC | MAIN, "MT6620 mr_th:\t0x%04x\n", cfg->rx_cfg.mr_th);
61     WCN_DBG(FM_NTC | MAIN, "MT6620 cqi_th:\t0x%04x\n", cfg->rx_cfg.cqi_th);
62     WCN_DBG(FM_NTC | MAIN, "MT6620 smg_th:\t0x%04x\n", cfg->rx_cfg.smg_th);
63     WCN_DBG(FM_NTC | MAIN, "MT6620 scan_ch_size:\t%d\n", cfg->rx_cfg.scan_ch_size);
64     WCN_DBG(FM_NTC | MAIN, "MT6620 seek_space:\t%d\n", cfg->rx_cfg.seek_space);
65     WCN_DBG(FM_NTC | MAIN, "MT6620 band:\t%d\n", cfg->rx_cfg.band);
66     WCN_DBG(FM_NTC | MAIN, "MT6620 band_freq_l:\t%d\n", cfg->rx_cfg.band_freq_l);
67     WCN_DBG(FM_NTC | MAIN, "MT6620 band_freq_h:\t%d\n", cfg->rx_cfg.band_freq_h);
68     WCN_DBG(FM_NTC | MAIN, "MT6620 scan_sort:\t%d\n", cfg->rx_cfg.scan_sort);
69     WCN_DBG(FM_NTC | MAIN, "MT6620 fake_ch_num:\t%d\n", cfg->rx_cfg.fake_ch_num);
70     WCN_DBG(FM_NTC | MAIN, "MT6620 fake_ch_rssi_th:\t%d\n", cfg->rx_cfg.fake_ch_rssi_th);
71
72     for (i = 0; i < cfg->rx_cfg.fake_ch_num; i++) {
73         WCN_DBG(FM_NTC | MAIN, "fake_ch:\t%d\n", cfg->rx_cfg.fake_ch[i]);
74     }
75
76     WCN_DBG(FM_NTC | MAIN, "de_emphasis:\t%d\n", cfg->rx_cfg.deemphasis);
77     WCN_DBG(FM_NTC | MAIN, "osc_freq:\t%d\n", cfg->rx_cfg.osc_freq);
78     WCN_DBG(FM_NTC | MAIN, "scan_hole_low:\t%d\n", cfg->tx_cfg.scan_hole_low);
79     WCN_DBG(FM_NTC | MAIN, "scan_hole_high:\t%d\n", cfg->tx_cfg.scan_hole_high);
80     WCN_DBG(FM_NTC | MAIN, "power_level:\t%d\n", cfg->tx_cfg.power_level);
81 #endif
82     return 0;
83 }
84
85 static fm_s32 MT6620cfg_item_handler(fm_s8 *grp, fm_s8 *key, fm_s8 *val, fm_cust_cfg *cfg)
86 {
87     fm_s32 ret = 0;
88     struct fm_rx_cust_cfg *rx_cfg = &cfg->rx_cfg;
89     struct fm_tx_cust_cfg *tx_cfg = &cfg->tx_cfg;
90
91     if (0 <= (ret = cfg_item_match(key, val, "FM_RX_RSSI_TH_LONG_MT6620", &rx_cfg->long_ana_rssi_th))) 
92     {//FMR_RSSI_TH_L = 0x0301
93         return ret;
94     } 
95     else if (0 <= (ret = cfg_item_match(key, val, "FM_RX_RSSI_TH_SHORT_MT6620", &rx_cfg->short_ana_rssi_th))) 
96     {
97         return ret;
98     } 
99     else if (0 <= (ret = cfg_item_match(key, val, "FM_RX_DESENSE_RSSI_MT6620", &rx_cfg->desene_rssi_th))) 
100     {
101         return ret;
102     } 
103     else if (0 <= (ret = cfg_item_match(key, val, "FM_RX_PAMD_TH_MT6620", &rx_cfg->pamd_th))) 
104     {
105         return ret;
106     } 
107     else if (0 <= (ret = cfg_item_match(key, val, "FM_RX_MR_TH_MT6620", &rx_cfg->mr_th))) 
108     {
109         return ret;
110     } 
111     else if (0 <= (ret = cfg_item_match(key, val, "FM_RX_ATDC_TH_MT6620", &rx_cfg->atdc_th))) 
112     {
113         return ret;
114     } 
115     else if (0 <= (ret = cfg_item_match(key, val, "FM_RX_PRX_TH_MT6620", &rx_cfg->prx_th))) 
116     {
117         return ret;
118     } 
119     else if (0 <= (ret = cfg_item_match(key, val, "FM_RX_SMG_TH_MT6620", &rx_cfg->smg_th))) 
120     {
121         return ret;
122     } 
123     else if (0 <= (ret = cfg_item_match(key, val, "FM_RX_DEEMPHASIS_MT6620", &rx_cfg->deemphasis))) 
124     {
125         return ret;
126     } 
127     else if (0 <= (ret = cfg_item_match(key, val, "FM_RX_OSC_FREQ_MT6620", &rx_cfg->osc_freq))) 
128     {
129         return ret;
130     } 
131     else if (0 <= (ret = cfg_item_match(key, val, "FMT_SCAN_HOLE_L_MT6620", &tx_cfg->scan_hole_low))) 
132     {
133         return ret;
134     } 
135     else if (0 <= (ret = cfg_item_match(key, val, "FMT_SCAN_HOLE_H_MT6620", &tx_cfg->scan_hole_high))) 
136     {
137         return ret;
138     } 
139     else if (0 <= (ret = cfg_item_match(key, val, "FMT_PWR_LVL_MAX_MT6620", &tx_cfg->power_level))) 
140     {
141         return ret;
142     } 
143     else 
144     {
145         WCN_DBG(FM_WAR | MAIN, "invalid key\n");
146         return -1;
147     }
148 /*    if (0 <= (ret = cfg_item_match(key, val, "FMR_RSSI_TH_L_MT6620", &rx_cfg->long_ana_rssi_th))) {//FMR_RSSI_TH_L = 0x0301
149         return ret;
150     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_RSSI_TH_S_MT6620", &rx_cfg->short_ana_rssi_th))) {
151         return ret;
152     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_CQI_TH_MT6620", &rx_cfg->cqi_th))) {
153         return ret;
154     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_MR_TH_MT6620", &rx_cfg->mr_th))) {
155         return ret;
156     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_SMG_TH_MT6620", &rx_cfg->smg_th))) {
157         return ret;
158     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_SCAN_CH_SIZE_MT6620", &rx_cfg->scan_ch_size))) {
159         return ret;
160     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_SCAN_SORT_MT6620", &rx_cfg->scan_sort))) {
161         return ret;
162     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_SEEK_SPACE_MT6620", &rx_cfg->seek_space))) {
163         return ret;
164     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_BAND_MT6620", &rx_cfg->band))) {
165         return ret;
166     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_BAND_FREQ_L_MT6620", &rx_cfg->band_freq_l))) {
167         return ret;
168     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_BAND_FREQ_H_MT6620", &rx_cfg->band_freq_h))) {
169         return ret;
170     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_FAKE_CH_MT6620", &rx_cfg->fake_ch[fm_index]))) {
171         fm_index += 1;
172         rx_cfg->fake_ch_num = (rx_cfg->fake_ch_num < fm_index) ? fm_index : rx_cfg->fake_ch_num;
173         return ret;
174     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_FAKE_CH_RSSI_MT6620", &rx_cfg->fake_ch_rssi_th))) {
175         return ret;
176     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_DEEMPHASIS_MT6620", &rx_cfg->deemphasis))) {
177         return ret;
178     } else if (0 <= (ret = cfg_item_match(key, val, "FMR_OSC_FREQ_MT6620", &rx_cfg->osc_freq))) {
179         return ret;
180     } */
181 }
182 static fm_s32 MT6620fm_cust_config_default(fm_cust_cfg *cfg)
183 {
184     FMR_ASSERT(cfg);
185
186     cfg->rx_cfg.long_ana_rssi_th = FM_RX_RSSI_TH_LONG_MT6620;
187     cfg->rx_cfg.short_ana_rssi_th = FM_RX_RSSI_TH_SHORT_MT6620;
188     cfg->rx_cfg.desene_rssi_th = FM_RX_DESENSE_RSSI_MT6620;
189     cfg->rx_cfg.pamd_th = FM_RX_PAMD_TH_MT6620;
190     cfg->rx_cfg.mr_th = FM_RX_MR_TH_MT6620;
191     cfg->rx_cfg.atdc_th = FM_RX_ATDC_TH_MT6620;
192     cfg->rx_cfg.prx_th = FM_RX_PRX_TH_MT6620;
193     cfg->rx_cfg.smg_th = FM_RX_SMG_TH_MT6620;
194     cfg->rx_cfg.deemphasis = FM_RX_DEEMPHASIS_MT6620;
195         cfg->rx_cfg.osc_freq = FM_RX_OSC_FREQ_MT6620;
196
197     cfg->tx_cfg.scan_hole_low = FM_TX_SCAN_HOLE_LOW_MT6620;
198     cfg->tx_cfg.scan_hole_high = FM_TX_SCAN_HOLE_HIGH_MT6620;
199     cfg->tx_cfg.power_level = FM_TX_PWR_LEVEL_MAX_MT6620;
200
201     return 0;
202 }
203
204 static fm_s32 MT6620fm_cust_config_file(const fm_s8 *filename, fm_cust_cfg *cfg)
205 {
206     fm_s32 ret = 0;
207     fm_s8 *buf = NULL;
208     fm_s32 file_len = 0;
209
210     if (!(buf = fm_zalloc(4096))) {
211         WCN_DBG(FM_ALT | MAIN, "-ENOMEM\n");
212         return -ENOMEM;
213     }
214
215 //    fm_index = 0;
216
217     file_len = fm_file_read(filename, buf, 4096, 0);
218
219     if (file_len <= 0) {
220         ret = -1;
221         goto out;
222     }
223
224     ret = cfg_parser(buf, MT6620cfg_item_handler, cfg);
225
226 out:
227
228     if (buf) {
229         fm_free(buf);
230     }
231
232     return ret;
233 }
234 #define MT6620_FM_CUST_CFG_PATH "etc/fmr/mt6620_fm_cust.cfg"
235 fm_s32 MT6620fm_cust_config_setup(const fm_s8 *filepath)
236 {
237     fm_s32 ret = 0;
238     fm_s8 *filep = NULL;
239     fm_s8 file_path[51] = {0};
240
241     MT6620fm_cust_config_default(&mt6620_fm_config);
242     WCN_DBG(FM_NTC | MAIN, "MT6620 FM default config\n");
243     MT6620fm_cust_config_print(&mt6620_fm_config);
244
245     if (!filepath) {
246         filep = MT6620_FM_CUST_CFG_PATH;
247     } else {
248         memcpy(file_path, filepath, (strlen(filepath) > 50) ? 50 : strlen(filepath));
249         filep = file_path;
250         trim_path(&filep);
251     }
252
253     ret = MT6620fm_cust_config_file(filep, &mt6620_fm_config);
254     WCN_DBG(FM_NTC | MAIN, "MT6620 FM cust config\n");
255     MT6620fm_cust_config_print(&mt6620_fm_config);
256         
257     return ret;
258 }
259
260 fm_u16 MT6620fm_cust_config_fetch(enum fm_cust_cfg_op op_code)
261 {
262 #if 0
263     fm_u16 tmp = 0;
264     fm_s32 i;
265     static fm_s32 fake_ch_idx = 0;
266
267     switch (op_code) {
268         //For FM RX
269     case FM_CFG_RX_RSSI_TH_LONG: {
270         tmp = mt6620_fm_config.rx_cfg.long_ana_rssi_th;
271         break;
272     }
273     case FM_CFG_RX_RSSI_TH_SHORT: {
274         tmp = mt6620_fm_config.rx_cfg.short_ana_rssi_th;
275         break;
276     }
277     case FM_CFG_RX_CQI_TH: {
278         tmp = mt6620_fm_config.rx_cfg.cqi_th;
279         break;
280     }
281     case FM_CFG_RX_MR_TH: {
282         tmp = mt6620_fm_config.rx_cfg.mr_th;
283         break;
284     }
285     case FM_CFG_RX_SMG_TH: {
286         tmp = mt6620_fm_config.rx_cfg.smg_th;
287         break;
288     }
289     case FM_CFG_RX_SCAN_CH_SIZE: {
290         tmp = mt6620_fm_config.rx_cfg.scan_ch_size;
291         break;
292     }
293     case FM_CFG_RX_SEEK_SPACE: {
294         tmp = mt6620_fm_config.rx_cfg.seek_space;
295         break;
296     }
297     case FM_CFG_RX_BAND: {
298         tmp = mt6620_fm_config.rx_cfg.band;
299         break;
300     }
301     case FM_CFG_RX_BAND_FREQ_L: {
302         tmp = mt6620_fm_config.rx_cfg.band_freq_l;
303         break;
304     }
305     case FM_CFG_RX_BAND_FREQ_H: {
306         tmp = mt6620_fm_config.rx_cfg.band_freq_h;
307         break;
308     }
309     case FM_CFG_RX_SCAN_SORT: {
310         tmp = mt6620_fm_config.rx_cfg.scan_sort;
311         break;
312     }
313     case FM_CFG_RX_FAKE_CH_NUM: {
314         tmp = mt6620_fm_config.rx_cfg.fake_ch_num;
315         break;
316     }
317     case FM_CFG_RX_FAKE_CH: {
318         tmp = mt6620_fm_config.rx_cfg.fake_ch[fake_ch_idx];
319         i = (mt6620_fm_config.rx_cfg.fake_ch_num > 0) ? mt6620_fm_config.rx_cfg.fake_ch_num : FAKE_CH_MAX;
320         fake_ch_idx++;
321         fake_ch_idx = fake_ch_idx % i;
322         break;
323     }
324     case FM_CFG_RX_FAKE_CH_RSSI: {
325         tmp = mt6620_fm_config.rx_cfg.fake_ch_rssi_th;
326         break;
327     }
328     case FM_CFG_RX_DEEMPHASIS: {
329         tmp = mt6620_fm_config.rx_cfg.deemphasis;
330         break;
331     }
332     case FM_CFG_RX_OSC_FREQ: {
333         tmp = mt6620_fm_config.rx_cfg.osc_freq;
334         break;
335     }
336     //For FM TX
337     case FM_CFG_TX_SCAN_HOLE_LOW: {
338         tmp = mt6620_fm_config.tx_cfg.scan_hole_low;
339         break;
340     }
341     case FM_CFG_TX_SCAN_HOLE_HIGH: {
342         tmp = mt6620_fm_config.tx_cfg.scan_hole_high;
343         break;
344     }
345     case FM_CFG_TX_PWR_LEVEL: {
346         tmp = mt6620_fm_config.tx_cfg.power_level;
347         break;
348     }
349     default:
350         break;
351     }
352
353     WCN_DBG(FM_DBG | MAIN, "mt6620_cust cfg %d: 0x%04x\n", op_code, tmp);
354     return tmp;
355 #endif
356         return 0;
357 }