8f508c12de07af6fdc32450ab7c53576f65baf2f
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rda5990 / rda_5990_power_ctrl / rda_5990_power_ctrl_by_gpio.c
1 /* ----------------------------------------------------------------------- *\r
2  *\r
3  This file created by albert RDA Inc\r
4  */\r
5 \r
6 #include <linux/module.h>\r
7 #include <linux/init.h>\r
8 #include <linux/slab.h>\r
9 #include <linux/i2c.h>\r
10 #include <linux/string.h>\r
11 #include <linux/rtc.h>       /* get the user-level API */\r
12 #include <linux/bcd.h>\r
13 #include <linux/list.h>\r
14 #include <linux/delay.h>\r
15 \r
16 \r
17 #include <linux/nfs_fs.h>\r
18 #include <linux/nfs_fs_sb.h>\r
19 #include <linux/nfs_mount.h>\r
20 #include <linux/fs.h>\r
21 #include <linux/file.h>\r
22 #include <linux/tty.h>\r
23 #include <linux/syscalls.h>\r
24 #include <asm/termbits.h>\r
25 #include <linux/serial.h>\r
26 \r
27 \r
28 #include <mach/mt6575_gpio.h>\r
29 #include <mach/mtk_rtc.h>\r
30 #include <linux/wakelock.h>\r
31 \r
32 #define RDA5890_USE_CRYSTAL  //if use share crystal should close this\r
33 #define RDA5990_USE_DCDC\r
34 \r
35 #define u32 unsigned int\r
36 #define u8 unsigned char\r
37 #define u16 unsigned short\r
38 \r
39 extern int rda_gpio_i2c_read_1_addr_2_data(uint8_t chipAddr, uint8_t regAddr, uint16_t *buffer);\r
40 extern int rda_gpio_i2c_write_1_addr_2_data(uint8_t chipAddr, uint8_t regAddr, uint16_t data);\r
41 extern int rda_gpio_i2c_read_4_addr_4_data(uint8_t chipAddr, uint32_t regAddr, uint32_t *buffer);\r
42 extern int rda_gpio_i2c_write_4_addr_4_data(uint8_t chipAddr, uint32_t regAddr, uint32_t data);\r
43 \r
44 \r
45 //#define RDA_I2C_CHANNEL               (0)\r
46 #define RDA_WIFI_CORE_ADDR (0x13)\r
47 #define RDA_WIFI_RF_ADDR (0x14) //correct add is 0x14\r
48 #define RDA_BT_CORE_ADDR (0x15)\r
49 #define RDA_BT_RF_ADDR (0x16)\r
50 \r
51 static struct mutex i2c_rw_lock;\r
52 static unsigned short wlan_version = 0;\r
53 static struct wake_lock rda_5990_wake_lock;\r
54 static struct delayed_work   rda_5990_sleep_worker;\r
55 \r
56 static u8 isBigEnded = 0;\r
57 \r
58 static u8 wifi_in_test_mode = 0;\r
59 \r
60 const u32 wifi_core_init_data[][2] = \r
61 {\r
62 \r
63 };\r
64 \r
65 u16 wifi_off_data[][2] = \r
66 {\r
67         { 0x3F, 0x0001 }, //page up\r
68         { 0x31, 0x0B40 }, //power off wifi\r
69         { 0x3F, 0x0000 }, //page down\r
70 };\r
71 \r
72 u16 wifi_en_data[][2] = \r
73 {\r
74     //item:VerD_wf_on_2012_02_08\r
75     {0x3f, 0x0001},\r
76 #ifdef RDA5990_USE_DCDC     /*houzhen update Mar 15 2012 */\r
77     {0x23, 0x8FA1},//20111001 higher AVDD voltage to improve EVM to 0x8f21 download current -1db 0x8fA1>>0x8bA1   \r
78 #else\r
79         {0x23, 0x0FA1},\r
80 #endif\r
81     {0x31, 0x0B40 }, //power off wifi\r
82 //    {0x22, 0xD3C7},//for ver.c 20111109, txswitch\r
83     {0x24, 0x80C8},//freq_osc_in[1:0]00  0x80C8 >> 0x80CB\r
84     {0x27, 0x4925},//for ver.c20111109, txswitch\r
85     //                {0x28, 0x80A1}, //BT_enable \r
86     {0x31, 0x8140},//enable wifi  \r
87     {0x32, 0x0113},//set_ rdenout_ldooff_wf=0; rden4in_ldoon_wf=1                                               \r
88     //                {0x39, 0x0004},   //uart switch to wf  \r
89     {0x3F, 0x0000}, //page down\r
90 };\r
91 \r
92 \r
93 u16 wifi_dc_cal_data[][2]=\r
94 {\r
95         {0x3f, 0x0000},\r
96         {0x30, 0x0248},\r
97         {0x30, 0x0249},\r
98         //{wait 200ms; } here\r
99 };\r
100 \r
101 u16 wifi_dig_reset_data[][2]=\r
102 {\r
103         {0x3F,  0x0001},\r
104         {0x31,  0x8D40},\r
105         {0x31,  0x8F40},\r
106         {0x31,  0x8b40},\r
107         {0x3F,  0x0000},\r
108 };\r
109 \r
110 u16 wifi_rf_init_data_verE[][2] = \r
111 {\r
112         {0x3f, 0x0000},\r
113         //{;;set_rf_swi},ch\r
114         {0x06, 0x0101},\r
115         {0x07, 0x0101},\r
116         {0x08, 0x0101},\r
117         {0x09, 0x0101},\r
118         {0x0A, 0x002C},//aain_0\r
119         {0x0D, 0x0507},\r
120         {0x0E, 0x2300},\r
121         {0x0F, 0x5689},//\r
122         //{;;//set_RF  },\r
123         {0x10, 0x0f78},//20110824\r
124         {0x11, 0x0602},\r
125         {0x13, 0x0652},//adc_tuning_bit[011]\r
126         {0x14, 0x8886},\r
127         {0x15, 0x0990},\r
128         {0x16, 0x049f},\r
129         {0x17, 0x0990},\r
130         {0x18, 0x049F},\r
131         {0x19, 0x3C01},\r
132         {0x1C, 0x0934},\r
133         {0x1D, 0xFF00},//for ver.D20120119for temperature 70 degree\r
134         //{0x1F, 0x01F8},//for ver.E should not set\r
135         //{0x1F, 0x0300},//for ver.E should not set\r
136         {0x20, 0x06E4},\r
137         {0x21, 0x0ACF},//for ver.c20111109,dr dac reset,dr txflt reset\r
138         {0x22, 0x24DC},\r
139         {0x23, 0x23FF},\r
140         {0x24, 0x00FC},\r
141         {0x26, 0x004F},//004F >> 005f premote pa \r
142         {0x27, 0x171D},///mdll*7\r
143         {0x28, 0x031D},///mdll*7\r
144         {0x2A, 0x2860},//et0x2849-8.5p  :yd 0x2861-7pf C1,C2=6.8p\r
145         {0x2B, 0x0800},//bbpll,or ver.c20111116\r
146         {0x32, 0x8a08},\r
147         {0x33, 0x1D02},//liuyanan\r
148         //{;;//agc_gain},\r
149         {0x36, 0x02f4}, //00F8;//gain_7\r
150         {0x37, 0x01f4}, //0074;//aain_6\r
151         {0x38, 0x21d4}, //0014;//gain_5\r
152         {0x39, 0x25d4}, //0414;//aain_4\r
153         {0x3A, 0x2584}, //1804;//gain_3\r
154         {0x3B, 0x2dc4}, //1C04;//aain_2\r
155         {0x3C, 0x2d04}, //1C02;//gain_1\r
156         {0x3D, 0x2c02}, //3C01;//gain_0\r
157         {0x33, 0x1502},//liuyanan\r
158         //{;;SET_channe},_to_11\r
159         {0x1B, 0x0001},//set_channel   \r
160         {0x30, 0x024D},\r
161         {0x29, 0xD468},\r
162         {0x29, 0x1468},\r
163         {0x30, 0x0249},\r
164         {0x3f, 0x0000},\r
165 };\r
166 \r
167 u16 wifi_rf_init_data[][2] = \r
168 {\r
169         {0x3f, 0x0000},\r
170         //{;;set_rf_swi},ch\r
171         {0x06, 0x0101},\r
172         {0x07, 0x0101},\r
173         {0x08, 0x0101},\r
174         {0x09, 0x0101},\r
175         {0x0A, 0x002C},//aain_0\r
176         {0x0D, 0x0507},\r
177         {0x0E, 0x2300},\r
178         {0x0F, 0x5689},//\r
179         //{;;//set_RF  },\r
180         {0x10, 0x0f78},//20110824\r
181         {0x11, 0x0602},\r
182         {0x13, 0x0652},//adc_tuning_bit[011]\r
183         {0x14, 0x8886},\r
184         {0x15, 0x0990},\r
185         {0x16, 0x049f},\r
186         {0x17, 0x0990},\r
187         {0x18, 0x049F},\r
188         {0x19, 0x3C01},\r
189         {0x1C, 0x0934},\r
190         {0x1D, 0xFF00},//for ver.D20120119for temperature 70 degree\r
191         //{0x1F, 0x01F8},//for ver.c20111109\r
192         {0x1F, 0x0300},//for burst tx 不锁\r
193         {0x20, 0x06E4},\r
194         {0x21, 0x0ACF},//for ver.c20111109,dr dac reset,dr txflt reset\r
195         {0x22, 0x24DC},\r
196         {0x23, 0x23FF},\r
197         {0x24, 0x00FC},\r
198         {0x26, 0x004F},//004F >> 005f premote pa \r
199         {0x27, 0x171D},///mdll*7\r
200         {0x28, 0x031D},///mdll*7\r
201         {0x2A, 0x2860},//et0x2849-8.5p  :yd 0x2861-7pf C1,C2=6.8p\r
202         {0x2B, 0x0800},//bbpll,or ver.c20111116\r
203         {0x32, 0x8a08},\r
204         {0x33, 0x1D02},//liuyanan\r
205         //{;;//agc_gain},\r
206         {0x36, 0x02f4}, //00F8;//gain_7\r
207         {0x37, 0x01f4}, //0074;//aain_6\r
208         {0x38, 0x21d4}, //0014;//gain_5\r
209         {0x39, 0x25d4}, //0414;//aain_4\r
210         {0x3A, 0x2584}, //1804;//gain_3\r
211         {0x3B, 0x2dc4}, //1C04;//aain_2\r
212         {0x3C, 0x2d04}, //1C02;//gain_1\r
213         {0x3D, 0x2c02}, //3C01;//gain_0\r
214         {0x33, 0x1502},//liuyanan\r
215         //{;;SET_channe},_to_11\r
216         {0x1B, 0x0001},//set_channel   \r
217         {0x30, 0x024D},\r
218         {0x29, 0xD468},\r
219         {0x29, 0x1468},\r
220         {0x30, 0x0249},\r
221         {0x3f, 0x0000},\r
222 };\r
223 \r
224 u16 wifi_uart_debug_data[][2] = \r
225 {\r
226   {0x3F,0x0001},\r
227   {0x28,0x80A1}, //BT_enable \r
228   {0x39,0x0004}, //uart switch to wf\r
229   {0x3f,0x0000},\r
230 };\r
231 \r
232 u16 wifi_tm_en_data[][2] =\r
233 {\r
234     {0x3F,0x0001},\r
235 #ifdef RDA5990_USE_DCDC     /*houzhen update Mar 15 2012 */\r
236     {0x23, 0x8FA1},//20111001 higher AVDD voltage to improve EVM to 0x8f21 download current -1db 0x8fA1>>0x8bA1   \r
237 #else\r
238         {0x23, 0x0FA1},\r
239 #endif\r
240     {0x22,0xD3C7},//for ver.c 20111109, tx\r
241         {0x24, 0x80C8},//freq_osc_in[1:0]00  0x80C8 >> 0x80CB \r
242         {0x27,0x4925},//for ver.c20111109, txs\r
243         {0x28,0x80A1}, //BT_enable            \r
244         {0x29,0x111F},                        \r
245         {0x31,0x8140},                        \r
246         {0x32,0x0113},//set_ rdenout_ldooff_wf\r
247         {0x39,0x0004},//uart switch to wf\r
248         {0x3f,0x0000},\r
249 };\r
250 \r
251 u16 wifi_tm_rf_init_data[][2] = \r
252 {\r
253         {0x3f, 0x0000},\r
254         //set_rf_switch                                                  \r
255         {0x06,0x0101},                                                     \r
256         {0x07,0x0101},                                                     \r
257         {0x08,0x0101},                                                     \r
258         {0x09,0x0101},                                                     \r
259         {0x0A,0x002C},//aain_0\r
260         {0x0D,0x0507},                                             \r
261         {0x0E,0x2300},//2012_02_20                                         \r
262         {0x0F,0x5689},//                                                   \r
263         //set_RF                                                            \r
264         {0x10,0x0f78},//20110824                                             \r
265         {0x11,0x0602},                                                     \r
266         {0x13,0x0652},//adc_tuning_bit[011]                               \r
267         {0x14,0x8886},                                                     \r
268         {0x15,0x0990},                                                     \r
269         {0x16,0x049f},                                                     \r
270         {0x17,0x0990},                                                     \r
271         {0x18,0x049F},                                                     \r
272         {0x19,0x3C01},//sdm_vbit[3:0]=1111                                 \r
273         {0x1C,0x0934},                                                     \r
274         {0x1D,0xCE00},//for ver.D20120119for temperature 70 degree         \r
275         {0x1F,0x0300},//div2_band_48g_dr=1;div2_band_48g_reg[8:0]1000000000\r
276         {0x20,0x06E4},                                                     \r
277         {0x21,0x0ACF},//for ver.c20111109,dr dac reset,dr txflt reset      \r
278         {0x22,0x24DC},                                                     \r
279         {0x23,0x23FF},                                                     \r
280         {0x24,0x00FC},                                                     \r
281         {0x26,0x004F},                                                     \r
282         {0x27,0x171D},///mdll*7                                            \r
283         {0x28,0x031D},///mdll*7                                            \r
284         {0x2A,0x2860},                                                     \r
285         {0x2B,0x0800},//bbpll,or ver.c20111116                             \r
286         {0x32,0x8a08},                                                     \r
287         {0x33,0x1D02},//liuyanan                                           \r
288         //agc_gain                                                          \r
289         {0x36,0x02f4}, //00F8;//gain_7                                     \r
290         {0x37,0x01f4}, //0074;//aain_6                                     \r
291         {0x38,0x21d4}, //0014;//gain_5                                     \r
292         {0x39,0x25d4}, //0414;//aain_4                                     \r
293         {0x3A,0x2584}, //1804;//gain_3                                     \r
294         {0x3B,0x2dc4}, //1C04;//aain_2                                     \r
295         {0x3C,0x2d04}, //1C02;//gain_1                                     \r
296         {0x3D,0x2c02}, //3C01;//gain_0                                     \r
297         //DC_CAL                                                            \r
298         {0x30,0x0248},                                                     \r
299         {0x30,0x0249},                                                     \r
300         //wait 200ms;                                                       \r
301         {0x33,0x1502},//liuyanan                                           \r
302         //SET_channel_to_11                                                 \r
303         {0x1B,0x0001},//set_channel     \r
304         {0x3f,0x0000},\r
305 };\r
306 \r
307 /*houzhen update Mar 15 2012\r
308   should be called when power up/down bt\r
309   */\r
310 static int rda5990_wf_setup_A2_power(int enable)\r
311 {\r
312         int ret;\r
313         u16 temp_data=0;\r
314         printk("***rda5990_wf_setup_A2_power start! \n");\r
315         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0001);\r
316         if(ret)\r
317                 goto err;\r
318 \r
319         if(enable)\r
320         {\r
321                 ret = rda_gpio_i2c_read_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x22, &temp_data);\r
322                 if(ret)\r
323                         goto err;\r
324                 printk("***0xA2 readback value:0x%X \n", temp_data);\r
325 \r
326                 temp_data |=0x0200;   /*en reg4_pa bit*/\r
327 #ifdef RDA5890_USE_CRYSTAL      \r
328                 temp_data &= ~(1 << 14); //disable xen_out\r
329 #endif\r
330                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x22, temp_data);\r
331                 if(ret)\r
332                         goto err;\r
333                 //read wlan version\r
334                 ret = rda_gpio_i2c_read_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x21, &temp_data);\r
335                 if(ret)\r
336                         goto err;\r
337                 else\r
338                         wlan_version = temp_data;\r
339         }\r
340         else\r
341         {\r
342                 ret = rda_gpio_i2c_read_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x28, &temp_data);\r
343                 if(ret)\r
344                         goto err;\r
345                 if(temp_data&0x8000)        // bt is on \r
346                 {\r
347                         goto out;\r
348                 }\r
349                 else\r
350                 {\r
351                         ret = rda_gpio_i2c_read_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x22, &temp_data);\r
352                         if(ret)\r
353                                 goto err;\r
354                         temp_data&=0xfdff;\r
355 \r
356                         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x22, temp_data);\r
357                         if(ret)\r
358                                 goto err;\r
359                 }\r
360                 wlan_version = 0;\r
361         }\r
362         printk("rda5990_wf_setup_A2_power, version:%d", wlan_version);\r
363 \r
364 out:\r
365         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0000);\r
366         if(ret)\r
367                 goto err;\r
368         printk("***rda5990_wf_setup_A2_power succeed! \n");\r
369         return 0;\r
370 \r
371 err:\r
372         printk("***rda5990_wf_setup_A2_power failed! \n");\r
373         return -1;\r
374 }\r
375 \r
376 \r
377 int rda_wifi_rf_init(void)\r
378 {\r
379         unsigned int count = 0;\r
380         int ret = 0;\r
381         mutex_lock(&i2c_rw_lock);\r
382         if( (wlan_version&0x1f) == 7)\r
383         {\r
384                 for(count = 0; count < sizeof(wifi_rf_init_data)/sizeof(wifi_rf_init_data[0]); count ++)\r
385                 {\r
386                         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, wifi_rf_init_data[count][0], wifi_rf_init_data[count][1]);\r
387                         if(ret)\r
388                                 goto err;\r
389                 }\r
390         }\r
391         else if((wlan_version&0x1f) == 4 || (wlan_version&0x1f)==5)\r
392         {\r
393                 for(count = 0; count < sizeof(wifi_rf_init_data_verE)/sizeof(wifi_rf_init_data_verE[0]); count ++)\r
394                 {\r
395                         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, wifi_rf_init_data_verE[count][0], wifi_rf_init_data_verE[count][1]);\r
396                         if(ret)\r
397                                 goto err;\r
398                 }\r
399         }\r
400         else\r
401         {\r
402                 printk("unknown version of this 5990 chip\n");\r
403                 goto err;\r
404         }\r
405         mutex_unlock(&i2c_rw_lock);\r
406         printk(KERN_INFO "***rda_wifi_rf_init_succceed \n");\r
407         msleep(5);   //5ms delay\r
408         return 0;\r
409 err:\r
410         mutex_unlock(&i2c_rw_lock);\r
411         printk(KERN_INFO "***rda_wifi_rf_init failed! \n");\r
412         return -1;\r
413 }\r
414 \r
415 int rda_wifi_dc_cal(void)\r
416 {\r
417         unsigned int count = 0;\r
418         int ret = 0;\r
419 \r
420     mutex_lock(&i2c_rw_lock);\r
421         for(count = 0; count < sizeof(wifi_dc_cal_data)/sizeof(wifi_dc_cal_data[0]); count ++)\r
422         {\r
423                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, wifi_dc_cal_data[count][0], wifi_dc_cal_data[count][1]);\r
424                 if(ret)\r
425                         goto err;\r
426         }\r
427 \r
428     mutex_unlock(&i2c_rw_lock);\r
429         printk(KERN_INFO "***rda_wifi_rf_dc_calsuccceed \n");\r
430         msleep(50);   //50ms delay\r
431         return 0;\r
432 \r
433 err:\r
434     mutex_unlock(&i2c_rw_lock);\r
435         printk(KERN_INFO "***rda_wifi_rf_dc_calf_failed! \n");\r
436         return -1;\r
437 }\r
438 \r
439 int rda_wifi_en(void)\r
440 {\r
441         unsigned int count = 0;\r
442         int ret = 0;\r
443 \r
444     mutex_lock(&i2c_rw_lock); \r
445         for(count = 0; count < sizeof(wifi_en_data)/sizeof(wifi_en_data[0]); count ++)\r
446         {\r
447                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, wifi_en_data[count][0], wifi_en_data[count][1]);\r
448                 if(ret)\r
449                         goto err;\r
450 \r
451                 if(wifi_en_data[count][0] == 0x31)\r
452                         msleep(12);\r
453         }\r
454 \r
455         ret=rda5990_wf_setup_A2_power(1);       //en pa_reg for wf\r
456         if(ret)\r
457                 goto err;\r
458 \r
459     mutex_unlock(&i2c_rw_lock);\r
460         msleep(8);   //8ms delay\r
461 \r
462         printk(KERN_INFO "***rda_wifi_en_succceed \n");\r
463         return 0;\r
464 err:\r
465      mutex_unlock(&i2c_rw_lock);\r
466         printk(KERN_INFO "***rda_wifi_power_on failed! \n");\r
467         return -1;\r
468 }\r
469 \r
470 int rda_wifi_debug_en(void)\r
471 {\r
472     unsigned int count = 0;\r
473     int ret = 0;\r
474     \r
475     mutex_lock(&i2c_rw_lock); \r
476                 for(count = 0; count < sizeof(wifi_uart_debug_data)/sizeof(wifi_uart_debug_data[0]); count ++)\r
477                 {\r
478               ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, wifi_uart_debug_data[count][0], wifi_uart_debug_data[count][1]);\r
479               if(ret)\r
480                   goto err;\r
481                 }\r
482 \r
483 err:\r
484     mutex_unlock(&i2c_rw_lock);\r
485     return ret;\r
486 }\r
487 \r
488 int rda_tm_wifi_en(void)\r
489 {\r
490         unsigned int count = 0;\r
491         int ret = 0;\r
492         unsigned short temp_data;\r
493 \r
494         for(count = 0; count < sizeof(wifi_tm_en_data)/sizeof(wifi_tm_en_data[0]); count ++)\r
495         {\r
496                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, wifi_tm_en_data[count][0], wifi_tm_en_data[count][1]);\r
497                 if(ret)\r
498                         goto err;\r
499         }\r
500 \r
501         msleep(8);   //8ms delay\r
502 \r
503     ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0001); //PAGE UP\r
504     if(ret)\r
505         goto err;\r
506  \r
507     ret = rda_gpio_i2c_read_1_addr_2_data(RDA_WIFI_RF_ADDR,0x21,&temp_data);\r
508     if(ret)\r
509         goto err;\r
510     else\r
511         wlan_version = temp_data;\r
512 \r
513     ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0000); //PAGE DOWN\r
514     if(ret)\r
515         goto err;\r
516 \r
517         printk(KERN_INFO "***rda_wifi_en_succceed \n");\r
518         return 0;\r
519 err:\r
520         printk(KERN_INFO "***rda_wifi_power_on failed! \n");\r
521         return -1;\r
522 }\r
523 \r
524 int rda_tm_wifi_rf_init(void)\r
525 {\r
526         unsigned int count = 0;\r
527         int ret = 0;\r
528 \r
529         for(count = 0; count < sizeof(wifi_tm_rf_init_data)/sizeof(wifi_tm_rf_init_data[0]); count ++)\r
530         {\r
531                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, wifi_tm_rf_init_data[count][0], wifi_tm_rf_init_data[count][1]);\r
532                 if(ret)\r
533                         goto err;\r
534         }\r
535 \r
536         printk(KERN_INFO "***rda_wifi_rf_init_succceed \n");\r
537         msleep(5);   //5ms delay\r
538         return 0;\r
539 \r
540 err:\r
541         printk(KERN_INFO "***rda_wifi_rf_init failed! \n");\r
542         return -1;\r
543 }\r
544 /*houzhen add 2012 04 09\r
545   add to ensure wf dig powerup\r
546   */\r
547 \r
548 int rda_wifi_dig_reset(void)\r
549 {\r
550         unsigned int count = 0;\r
551         int ret = 0;\r
552         msleep(8);   //8ms delay\r
553     mutex_lock(&i2c_rw_lock);\r
554 \r
555         for(count = 0; count < sizeof(wifi_dig_reset_data)/sizeof(wifi_dig_reset_data[0]); count ++)\r
556         {\r
557                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, wifi_dig_reset_data[count][0], wifi_dig_reset_data[count][1]);\r
558                 if(ret)\r
559                         goto err;\r
560         }\r
561 \r
562     mutex_unlock(&i2c_rw_lock);\r
563         msleep(8);   //8ms delay\r
564         printk(KERN_INFO "***rda_wifi_dig_reset \n");\r
565         return 0;\r
566 err:\r
567     mutex_unlock(&i2c_rw_lock);\r
568         printk(KERN_INFO "***rda_wifi_dig_reset failed! \n"); \r
569         return -1;\r
570 }\r
571 \r
572 int rda_wlan_version(void)\r
573 {\r
574         printk("******version %x \n", wlan_version);\r
575         return wlan_version;\r
576 }\r
577 \r
578 int rda_wifi_power_off(void)\r
579 {\r
580         unsigned int count = 0;\r
581         int ret = 0;\r
582         u16 temp=0x0000;\r
583         printk(KERN_INFO "rda_wifi_power_off \n");\r
584 \r
585 \r
586     mutex_lock(&i2c_rw_lock);\r
587         ret=rda5990_wf_setup_A2_power(0);   //disable pa_reg for wf\r
588         if(ret)\r
589                 goto err;\r
590 \r
591         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0001);   //page up\r
592         if(ret)\r
593                 goto err;\r
594 \r
595         ret = rda_gpio_i2c_read_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x28, &temp);   //poll bt status\r
596         if(ret)\r
597                 goto err;\r
598 \r
599         if(temp&0x8000)\r
600         {\r
601                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0000);   //page down\r
602                 if(ret)\r
603                         goto err;\r
604 \r
605                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x0f, 0x2223);   // set antenna for bt\r
606                 if(ret)\r
607                         goto err;\r
608 \r
609         }\r
610 \r
611 \r
612         for(count = 0; count < sizeof(wifi_off_data)/sizeof(wifi_off_data[0]); count ++)\r
613         {\r
614                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, wifi_off_data[count][0], wifi_off_data[count][1]);\r
615                 if(ret)\r
616                         goto err;\r
617         }\r
618         printk(KERN_INFO "***rda_wifi_power_off success!!! \n");\r
619 \r
620 \r
621 \r
622     mutex_unlock(&i2c_rw_lock);\r
623         return 0;\r
624 \r
625 err:\r
626     mutex_unlock(&i2c_rw_lock);\r
627         printk(KERN_INFO "***rda_wifi_power_off failed! \n");\r
628         return -1;\r
629 \r
630 }\r
631 \r
632 int rda_wifi_power_on(void)\r
633 {\r
634         int ret;\r
635         char retry = 3;\r
636 \r
637 \r
638 _retry:\r
639 \r
640         if(!wifi_in_test_mode)\r
641         {\r
642                 ret = rda_wifi_en();    \r
643                 if(ret < 0)\r
644                         goto err;\r
645 \r
646                 ret = rda_wifi_rf_init();       \r
647                 if(ret < 0)\r
648                         goto err;\r
649 \r
650                 ret = rda_wifi_dc_cal();        \r
651                 if(ret < 0)\r
652                         goto err;\r
653 \r
654                 msleep(20);   //20ms delay\r
655                 ret=rda_wifi_dig_reset();   //houzhen add to ensure wf power up safely\r
656 \r
657                 if(ret < 0)\r
658                         goto err;\r
659                 msleep(20);   //20ms delay\r
660         }\r
661         else\r
662         {\r
663                 ret = rda_tm_wifi_en();\r
664                 if(ret < 0)\r
665                         goto err;\r
666 \r
667                 ret = rda_tm_wifi_rf_init();\r
668                 if(ret < 0)\r
669                         goto err;\r
670         }\r
671         printk(KERN_INFO "rda_wifi_power_on_succeed!! \n");\r
672 \r
673         return 0;\r
674 \r
675 err:\r
676         printk(KERN_INFO "rda_wifi_power_on_failed retry:%d \n", retry);\r
677         if(retry -- > 0)\r
678         {   \r
679                 rda_wifi_power_off();\r
680                 goto _retry;\r
681         }\r
682 \r
683         return -1;\r
684 }\r
685 \r
686 int rda_fm_power_on(void)\r
687 {\r
688         int ret = 0;\r
689         u16 temp = 0;\r
690 \r
691 \r
692         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0001);   // page down\r
693         if(ret < 0){\r
694                 printk(KERN_INFO "%s() write address(0x%02x) with value(0x%04x) failed! \n", __func__, 0x3f, 0x0001);\r
695                 return -1;\r
696         }\r
697         ret = rda_gpio_i2c_read_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x22, &temp);           //read 0xA2\r
698         if(ret < 0){\r
699                 printk(KERN_INFO "%s() read from address(0x%02x) failed! \n", __func__, 0x22);\r
700                 return -1;\r
701         }\r
702         temp = temp & (~(1 << 15));             //clear bit[15]\r
703         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x22, temp);           //write back\r
704         if(ret < 0){\r
705                 printk(KERN_INFO "%s() write address(0x%02x) with value(0x%04x) failed! \n", __func__, 0x3f, 0x0001);\r
706                 return -1;\r
707         }\r
708         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0000);   // page up\r
709         if(ret < 0){\r
710                 printk(KERN_INFO "%s() write address(0x%02x) with value(0x%04x) failed! \n", __func__, 0x3f, 0x0001);\r
711                 return -1;\r
712         }\r
713 \r
714         return 0;\r
715 }\r
716 \r
717 int rda_fm_power_off(void)\r
718 {\r
719         int ret = 0;\r
720         u16 temp = 0;\r
721 \r
722 \r
723         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0001);   // page down\r
724         if(ret < 0){\r
725                 printk(KERN_INFO "%s() write address(0x%02x) with value(0x%04x) failed! \n", __func__, 0x3f, 0x0001);\r
726                 return -1;\r
727         }\r
728         ret = rda_gpio_i2c_read_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x22, &temp);           //read 0xA2\r
729         if(ret < 0){\r
730                 printk(KERN_INFO "%s() read from address(0x%02x) failed! \n", __func__, 0x22);\r
731                 return -1;\r
732         }\r
733         temp = temp | (1 << 15);                //set bit[15]\r
734         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x22, temp);           //write back\r
735         if(ret < 0){\r
736                 printk(KERN_INFO "%s() write address(0x%02x) with value(0x%04x) failed! \n", __func__, 0x3f, 0x0001);\r
737                 return -1;\r
738         }\r
739         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, 0x3f, 0x0000);   // page up\r
740         if(ret < 0){\r
741                 printk(KERN_INFO "%s() write address(0x%02x) with value(0x%04x) failed! \n", __func__, 0x3f, 0x0001);\r
742                 return -1;\r
743         }\r
744 \r
745         return 0;\r
746 }\r
747 \r
748 \r
749 u16 rda_5990_bt_off_data[][2] = \r
750 {\r
751         {0x3f, 0x0001 }, //pageup\r
752         {0x28, 0x00A1 }, //power off bt\r
753         {0x3f, 0x0000 }, //pagedown\r
754 };\r
755 \r
756 /*houzhen update 2012 03 06*/\r
757 u16 rda_5990_bt_en_data[][2] = \r
758 {\r
759     {0x3f, 0x0001 },            //pageup\r
760 #ifdef RDA5990_USE_DCDC    \r
761     {0x23, 0x8FA1},               // //20111001 higher AVDD voltage to improve EVM\r
762 #else\r
763         {0x23, 0x0FA1},\r
764 #endif \r
765         {0x24, 0x80C8},           // ;//freq_osc_in[1:0]00      \r
766         {0x26, 0x47A5},           //  reg_vbit_normal_bt[2:0] =111\r
767         {0x27, 0x4925},           // //for ver.c20111109, txswitch\r
768         {0x29, 0x111F},           // // rden4in_ldoon_bt=1      \r
769         {0x32, 0x0111},           // set_ rdenout_ldooff_wf=0;                                           \r
770         {0x39, 0x0000},           //      //uart switch to bt\r
771 \r
772         {0x28, 0x80A1},         // bt en\r
773         {0x3f, 0x0000},         //pagedown\r
774 };\r
775 \r
776 \r
777 u16 rda_5990_bt_dc_cal[][2] = \r
778 {\r
779         {0x3f, 0x0000 }, \r
780         {0x30, 0x0129 },\r
781         {0x30, 0x012B },\r
782         {0x3f, 0x0000 }, \r
783 };\r
784 \r
785 \r
786 u16 rda_5990_bt_set_rf_switch_data[][2] = \r
787 {\r
788         {0x3f, 0x0000 }, \r
789         {0x0F, 0x2223 },\r
790         {0x3f, 0x0000 }, \r
791 };\r
792 \r
793 \r
794 u16 RDA5990_bt_enable_clk_data[][2] = \r
795 {\r
796         {0x3f, 0x0000 }, \r
797         {0x30, 0x0040 },\r
798         {0x2a, 0x285d },\r
799         {0x3f, 0x0000 }, \r
800 };\r
801 \r
802 u16 RDA5990_bt_dig_reset_data[][2] = \r
803 {\r
804         {0x3f, 0x0001 }, //pageup\r
805         {0x28, 0x86A1 },\r
806         {0x28, 0x87A1 },\r
807         {0x28, 0x85A1 },\r
808         {0x3f, 0x0000 }, //pagedown\r
809 };\r
810 \r
811 /*houzhen update 2012 03 06*/\r
812 u16 rda_5990_bt_rf_data[][2] = \r
813 {\r
814         {0x3f, 0x0000}, //pagedown\r
815         {0x01, 0x1FFF},\r
816         {0x06, 0x07F7},\r
817         {0x08, 0x29E7},\r
818         {0x09, 0x0520},\r
819         {0x0B, 0x03DF},\r
820         {0x0C, 0x85E8},\r
821         {0x0F, 0x0DBC},\r
822         {0x12, 0x07F7},\r
823         {0x13, 0x0327},\r
824         {0x14, 0x0CCC},\r
825         {0x15, 0x0526},\r
826         {0x16, 0x8918},\r
827         {0x18, 0x8800},\r
828         {0x19, 0x10C8},\r
829         {0x1A, 0x9078},\r
830         {0x1B, 0x80E2},\r
831         {0x1C, 0x361F},\r
832         {0x1D, 0x4363},\r
833         {0x1E, 0x303F},\r
834         {0x23, 0x2222},\r
835         {0x24, 0x359D},\r
836         {0x27, 0x0011},\r
837         {0x28, 0x124F},\r
838         {0x39, 0xA5FC},\r
839         {0x3f, 0x0001}, //page 1\r
840         {0x00, 0x043F},\r
841         {0x01, 0x467F},\r
842         {0x02, 0x28FF},\r
843         {0x03, 0x67FF},\r
844         {0x04, 0x57FF},\r
845         {0x05, 0x7BFF},\r
846         {0x06, 0x3FFF},\r
847         {0x07, 0x7FFF},\r
848         {0x18, 0xF3F5},\r
849         {0x19, 0xF3F5},\r
850         {0x1A, 0xE7F3},\r
851         {0x1B, 0xF1FF},\r
852         {0x1C, 0xFFFF},\r
853         {0x1D, 0xFFFF},\r
854         {0x1E, 0xFFFF},\r
855         {0x1F, 0xFFFF},\r
856         //      {0x22, 0xD3C7}, \r
857         //      {0x23, 0x8fa1},\r
858         //      {0x24, 0x80c8},\r
859         //      {0x26, 0x47A5},\r
860         //      {0x27, 0x4925},\r
861         //      {0x28, 0x85a1},\r
862         //      {0x29, 0x111f},\r
863         //      {0x32, 0x0111},\r
864         //      {0x39, 0x0000},\r
865         {0x3f, 0x0000}, //pagedown\r
866 };\r
867 \r
868 /*houzhen update Mar 15 2012\r
869   should be called when power up/down bt\r
870   */\r
871 static int rda5990_bt_setup_A2_power(int enable)\r
872 {\r
873         int ret;\r
874         u16 temp_data=0;\r
875 \r
876         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, 0x3f, 0x0001);\r
877         if(ret)\r
878                 goto err;\r
879 \r
880         if(enable)\r
881         {\r
882                 ret = rda_gpio_i2c_read_1_addr_2_data(RDA_BT_RF_ADDR, 0x22, &temp_data);\r
883                 if(ret)\r
884                         goto err;\r
885                 printk(KERN_INFO "***0xA2 readback value:0x%X \n", temp_data);\r
886 \r
887                 temp_data |=0x0200;   /*en reg4_pa bit*/\r
888 \r
889                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, 0x22, temp_data);\r
890                 if(ret)\r
891                         goto err;               \r
892         }\r
893         else\r
894         {\r
895                 ret = rda_gpio_i2c_read_1_addr_2_data(RDA_BT_RF_ADDR, 0x31, &temp_data);\r
896                 if(ret)\r
897                         goto err;\r
898                 if(temp_data&0x8000)        // wf is on \r
899                 {\r
900                         goto out;\r
901                 }\r
902                 else\r
903                 {\r
904                         ret = rda_gpio_i2c_read_1_addr_2_data(RDA_BT_RF_ADDR, 0x22, &temp_data);\r
905                         if(ret)\r
906                                 goto err;\r
907                         temp_data&=0xfdff;\r
908 \r
909                         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, 0x22, temp_data);\r
910                         if(ret)\r
911                                 goto err;\r
912                 }\r
913 \r
914         }\r
915 \r
916 \r
917 out:\r
918         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, 0x3f, 0x0000);\r
919         if(ret)\r
920                 goto err;\r
921         return 0;\r
922 \r
923 err:\r
924         printk(KERN_INFO "***rda5990_bt_setup_A2_power failed! \n");\r
925         return -1;\r
926 }\r
927 \r
928 int rda_bt_power_off(void);\r
929 \r
930 int rda_bt_power_on(void)\r
931 {\r
932         unsigned int count = 0;\r
933         int ret = 0;\r
934 \r
935         printk(KERN_INFO "rda_bt_power_on \n");\r
936 \r
937 \r
938     mutex_lock(&i2c_rw_lock);\r
939 \r
940         for(count = 0; count < sizeof(rda_5990_bt_en_data)/sizeof(rda_5990_bt_en_data[0]); count ++)\r
941         {\r
942                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, rda_5990_bt_en_data[count][0], rda_5990_bt_en_data[count][1]);\r
943 \r
944                 if(ret)\r
945                         goto err;\r
946         }\r
947 \r
948         ret=rda5990_bt_setup_A2_power(1);       \r
949         if(ret)\r
950         {   \r
951                 printk(KERN_INFO "***rda5990_bt_setup_A2_power fail!!! \n");\r
952                 goto err;\r
953         }\r
954 \r
955         printk(KERN_INFO "***rda_bt_power_on success!!! \n");\r
956 \r
957     mutex_unlock(&i2c_rw_lock);\r
958         /*houzhen update 2012 03 06*/\r
959         msleep(10);     //delay 10 ms after power on\r
960 \r
961 \r
962         return 0;\r
963 err:\r
964     mutex_unlock(&i2c_rw_lock);\r
965         printk(KERN_INFO "***rda_bt_power_on failed! \n");\r
966         return -1;\r
967 \r
968 }\r
969 \r
970 int rda_bt_power_off(void)\r
971 {\r
972         unsigned int count = 0;\r
973         int ret = 0;\r
974         printk(KERN_INFO "rda_bt_power_off \n");\r
975 \r
976 \r
977     mutex_lock(&i2c_rw_lock);\r
978         for(count = 0; count < sizeof(rda_5990_bt_off_data)/sizeof(rda_5990_bt_off_data[0]); count ++)\r
979         {\r
980                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, rda_5990_bt_off_data[count][0], rda_5990_bt_off_data[count][1]);\r
981                 if(ret)\r
982                         goto err;\r
983         }\r
984         msleep(10);   //10ms\r
985         printk(KERN_INFO "***rda_bt_power_off success!!! \n");\r
986 \r
987         ret=rda5990_bt_setup_A2_power(0);//disable ldo_pa reg \r
988         if(ret)\r
989                 goto err;\r
990 \r
991 \r
992 \r
993     mutex_unlock(&i2c_rw_lock);    \r
994         return 0;\r
995 \r
996 err:\r
997     mutex_unlock(&i2c_rw_lock);\r
998         printk(KERN_INFO "***rda_bt_power_off failed! \n");\r
999         return -1;\r
1000 \r
1001 }\r
1002 \r
1003 \r
1004 int RDA5990_bt_rf_init(void)\r
1005 {\r
1006         unsigned int count = 0;\r
1007         int ret = 0;\r
1008         printk(KERN_INFO "RDA5990_bt_rf_init \n");\r
1009 \r
1010 \r
1011     mutex_lock(&i2c_rw_lock);\r
1012         for(count = 0; count < sizeof(rda_5990_bt_rf_data)/sizeof(rda_5990_bt_rf_data[0]); count ++)\r
1013         {\r
1014                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, rda_5990_bt_rf_data[count][0], rda_5990_bt_rf_data[count][1]);\r
1015                 if(ret)\r
1016                         goto err;\r
1017         }\r
1018 \r
1019     mutex_unlock(&i2c_rw_lock);\r
1020         printk(KERN_INFO "***RDA5990_bt_rf_init success!!! \n");\r
1021         msleep(5);   //5ms\r
1022         return 0;\r
1023 \r
1024 err:\r
1025     mutex_unlock(&i2c_rw_lock);\r
1026         printk(KERN_INFO "***RDA5990_bt_rf_init failed! \n");\r
1027         return -1;\r
1028 \r
1029 }\r
1030 \r
1031 \r
1032 \r
1033 /*houzhen add 2012 04 09\r
1034   add to ensure bt dig powerup\r
1035   */\r
1036 \r
1037 int RDA5990_bt_dig_reset(void)\r
1038 {\r
1039         unsigned int count = 0;\r
1040         int ret = 0;\r
1041 \r
1042         printk(KERN_INFO "RDA5990_bt_dig_reset \n");\r
1043 \r
1044     mutex_lock(&i2c_rw_lock);\r
1045         for(count = 0; count < sizeof(RDA5990_bt_dig_reset_data)/sizeof(RDA5990_bt_dig_reset_data[0]); count ++)\r
1046         {\r
1047                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, RDA5990_bt_dig_reset_data[count][0], RDA5990_bt_dig_reset_data[count][1]);\r
1048                 if(ret)\r
1049                         goto err;\r
1050         }\r
1051 \r
1052     mutex_unlock(&i2c_rw_lock);\r
1053         printk(KERN_INFO "***RDA5990_bt_dig_reset success!!! \n");\r
1054         msleep(5);   //5ms\r
1055         return 0;\r
1056 \r
1057 err:\r
1058     mutex_unlock(&i2c_rw_lock);\r
1059         printk(KERN_INFO "***RDA5990_bt_dig_reset failed! \n");\r
1060         return -1;\r
1061 \r
1062 }\r
1063 \r
1064 \r
1065 int RDA5990_bt_dc_cal(void)\r
1066 {\r
1067         unsigned int count = 0;\r
1068         int ret = 0;\r
1069         printk(KERN_INFO "rda_bt_dc_cal \n");\r
1070 \r
1071     mutex_lock(&i2c_rw_lock);\r
1072 \r
1073         for(count = 0; count < sizeof(rda_5990_bt_dc_cal)/sizeof(rda_5990_bt_dc_cal[0]); count ++)\r
1074         {\r
1075                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, rda_5990_bt_dc_cal[count][0], rda_5990_bt_dc_cal[count][1]);\r
1076                 if(ret)\r
1077                         goto err;\r
1078         }\r
1079 \r
1080     mutex_unlock(&i2c_rw_lock);\r
1081         printk(KERN_INFO "***rda_bt_dc_cal success!!! \n");\r
1082         msleep(200);   //200ms\r
1083 \r
1084         return 0;\r
1085 \r
1086 err:\r
1087     mutex_unlock(&i2c_rw_lock);\r
1088         printk(KERN_INFO "***rda_bt_dc_cal  failed! \n");\r
1089         return -1;\r
1090 \r
1091 }\r
1092 \r
1093 \r
1094 \r
1095 /*houzhen update Mar 15 2012 \r
1096   bypass RDA5990_bt_set_rf_switch when wf is already on\r
1097   */\r
1098 \r
1099 int RDA5990_bt_set_rf_switch(void)\r
1100 {\r
1101         unsigned int count = 0;\r
1102         int ret = 0;\r
1103         u16 temp_data=0;\r
1104         printk(KERN_INFO "RDA5990_bt_set_rf_switch \n");\r
1105 \r
1106 \r
1107     mutex_lock(&i2c_rw_lock);\r
1108 \r
1109         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, 0x3f, 0x0001);\r
1110         if(ret)\r
1111                 goto err;       \r
1112 \r
1113         ret = rda_gpio_i2c_read_1_addr_2_data(RDA_BT_RF_ADDR, 0x31, &temp_data);\r
1114 \r
1115         if(ret)\r
1116                 goto err;       \r
1117 \r
1118         if(temp_data&0x8000)   // if wf is already on\r
1119         {\r
1120 \r
1121                 printk(KERN_INFO "wf already en, bypass RDA5990_bt_set_rf_switch function \n");\r
1122                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, 0x3f, 0x0000);\r
1123                 if(ret)\r
1124                         goto err;       \r
1125         mutex_unlock(&i2c_rw_lock);     \r
1126                 return 0;\r
1127         }\r
1128 \r
1129         for(count = 0; count < sizeof(rda_5990_bt_set_rf_switch_data)/sizeof(rda_5990_bt_set_rf_switch_data[0]); count ++)\r
1130         {\r
1131                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, rda_5990_bt_set_rf_switch_data[count][0], rda_5990_bt_set_rf_switch_data[count][1]);\r
1132                 if(ret)\r
1133                         goto err;           \r
1134         }\r
1135 \r
1136     mutex_unlock(&i2c_rw_lock);\r
1137         printk(KERN_INFO "***RDA5990_bt_set_rf_switch success!!! \n");\r
1138         msleep(50);   //50ms\r
1139         return 0;\r
1140 \r
1141 err:\r
1142     mutex_unlock(&i2c_rw_lock);\r
1143         printk(KERN_INFO "***RDA5990_bt_set_rf_switch  failed! \n");\r
1144         return -1;\r
1145 \r
1146 }\r
1147 \r
1148 \r
1149 /*houzhen update Mar 15 2012 \r
1150   bypass RDA5990_bt_enable_clk when wf is already on\r
1151   */\r
1152 \r
1153 int RDA5990_bt_enable_clk(void)\r
1154 {\r
1155         unsigned int count = 0;\r
1156         int ret = 0;\r
1157         u16 temp_data=0;\r
1158         printk(KERN_INFO "RDA5990_bt_enable_clk \n");\r
1159 \r
1160     mutex_lock(&i2c_rw_lock);\r
1161         ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, 0x3f, 0x0001);\r
1162         if(ret)\r
1163                 goto err;       \r
1164 \r
1165         ret = rda_gpio_i2c_read_1_addr_2_data(RDA_BT_RF_ADDR, 0x31, &temp_data);\r
1166 \r
1167         if(ret)\r
1168                 goto err;       \r
1169 \r
1170         if(temp_data&0x8000)   // if wf is already on\r
1171         {\r
1172 \r
1173                 printk(KERN_INFO "wf already en, bypass RDA5990_bt_enable_clk function \n");\r
1174                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_BT_RF_ADDR, 0x3f, 0x0000);\r
1175                 if(ret)\r
1176                         goto err;       \r
1177         mutex_unlock(&i2c_rw_lock);\r
1178                 return 0;\r
1179         }\r
1180 \r
1181 \r
1182         for(count = 0; count < sizeof(RDA5990_bt_enable_clk_data)/sizeof(RDA5990_bt_enable_clk_data[0]); count ++)\r
1183         {\r
1184                 ret = rda_gpio_i2c_write_1_addr_2_data(RDA_WIFI_RF_ADDR, RDA5990_bt_enable_clk_data[count][0], RDA5990_bt_enable_clk_data[count][1]);\r
1185                 if(ret)\r
1186                         goto err;       \r
1187         }\r
1188 \r
1189     mutex_unlock(&i2c_rw_lock);\r
1190         printk(KERN_INFO "***RDA5990_bt_enable_clk success!!! \n");\r
1191         msleep(50);   //50ms\r
1192         return 0;\r
1193 \r
1194 err:\r
1195     mutex_unlock(&i2c_rw_lock);\r
1196         printk(KERN_INFO "***RDA5990_bt_enable_clk  failed! \n");\r
1197         return -1;\r
1198 \r
1199 }\r
1200 \r
1201 extern void mt_combo_bgf_enable_irq(void);\r
1202 extern void mt_combo_bgf_disable_irq(void);\r
1203 \r
1204 \r
1205 #define RDA_BT_IOCTL_MAGIC 'u'\r
1206 #define RDA_BT_POWER_ON_IOCTL _IO(RDA_BT_IOCTL_MAGIC ,0x01)\r
1207 #define RD_BT_RF_INIT_IOCTL   _IO(RDA_BT_IOCTL_MAGIC ,0x02)\r
1208 #define RD_BT_DC_CAL_IOCTL    _IO(RDA_BT_IOCTL_MAGIC ,0x03)\r
1209 #define RD_BT_SET_RF_SWITCH_IOCTL _IO(RDA_BT_IOCTL_MAGIC ,0x04)\r
1210 #define RDA_BT_POWER_OFF_IOCTL _IO(RDA_BT_IOCTL_MAGIC ,0x05)\r
1211 #define RDA_BT_EN_CLK _IO(RDA_BT_IOCTL_MAGIC ,0x06)\r
1212 #define RD_BT_DC_DIG_RESET_IOCTL    _IO(RDA_BT_IOCTL_MAGIC ,0x07)\r
1213 \r
1214 #define RDA_WIFI_POWER_ON_IOCTL    _IO(RDA_BT_IOCTL_MAGIC ,0x10)\r
1215 #define RDA_WIFI_POWER_OFF_IOCTL    _IO(RDA_BT_IOCTL_MAGIC ,0x11)\r
1216 #define RDA_WIFI_POWER_SET_TEST_MODE_IOCTL    _IO(RDA_BT_IOCTL_MAGIC ,0x12)\r
1217 #define RDA_WIFI_POWER_CANCEL_TEST_MODE_IOCTL    _IO(RDA_BT_IOCTL_MAGIC ,0x13)\r
1218 #define RDA_WIFI_DEBUG_MODE_IOCTL    _IO(RDA_BT_IOCTL_MAGIC ,0x14)\r
1219 \r
1220 static int rda_5990_pw_ioctl(struct file *file, unsigned int cmd, unsigned long arg)\r
1221 {\r
1222         int ret = 0;\r
1223 \r
1224         switch(cmd)\r
1225         {\r
1226                 case RDA_WIFI_POWER_ON_IOCTL:\r
1227             ret = rda_wifi_power_on();\r
1228                         break;\r
1229 \r
1230                 case RDA_WIFI_POWER_OFF_IOCTL:\r
1231             ret = rda_wifi_power_off();\r
1232                         break;\r
1233 \r
1234                 case RDA_WIFI_POWER_SET_TEST_MODE_IOCTL:\r
1235                         wifi_in_test_mode = 1;\r
1236                         printk("****set rda wifi in test mode");\r
1237                         break;\r
1238 \r
1239                 case RDA_WIFI_POWER_CANCEL_TEST_MODE_IOCTL:\r
1240                         wifi_in_test_mode = 0;\r
1241                         printk("****set rda wifi in normal mode");\r
1242                         break;\r
1243 \r
1244         case RDA_WIFI_DEBUG_MODE_IOCTL:\r
1245             ret = rda_wifi_debug_en();\r
1246             break;\r
1247                 case RDA_BT_POWER_ON_IOCTL:\r
1248                         {\r
1249                                 ret = rda_bt_power_on();\r
1250                                 mt_combo_bgf_enable_irq();\r
1251                         }\r
1252                         break;\r
1253 \r
1254                         /* should call thif function after bt_power_on*/\r
1255                 case RDA_BT_EN_CLK:\r
1256                         ret = RDA5990_bt_enable_clk();\r
1257                         break;\r
1258 \r
1259                 case RD_BT_RF_INIT_IOCTL:\r
1260                         ret = RDA5990_bt_rf_init();\r
1261                         break;\r
1262 \r
1263                 case RD_BT_DC_CAL_IOCTL:        \r
1264                         ret = RDA5990_bt_dc_cal();\r
1265                         break;\r
1266 \r
1267                 case RD_BT_DC_DIG_RESET_IOCTL:  \r
1268                         ret = RDA5990_bt_dig_reset();\r
1269                         break;\r
1270 \r
1271                 case RD_BT_SET_RF_SWITCH_IOCTL:\r
1272                         ret = RDA5990_bt_set_rf_switch();                       \r
1273                         break;\r
1274 \r
1275                 case RDA_BT_POWER_OFF_IOCTL:\r
1276                         {\r
1277                                 mt_combo_bgf_disable_irq();\r
1278                                 ret = rda_bt_power_off();               \r
1279                         }\r
1280                         break;\r
1281 \r
1282                 default:\r
1283                         break;\r
1284         }\r
1285 \r
1286         printk(KERN_INFO "rda_bt_pw_ioctl cmd=0x%02x \n", cmd);\r
1287 \r
1288         return ret;\r
1289 }       \r
1290 \r
1291 static int rda_5990_major;\r
1292 static struct class *rda_5990_class = NULL;\r
1293 static const struct file_operations rda_5990_operations = {\r
1294         .owner = THIS_MODULE,\r
1295         .unlocked_ioctl = rda_5990_pw_ioctl,\r
1296         .release = NULL\r
1297 };\r
1298 \r
1299 void rda_5990_sleep_worker_task(struct work_struct *work)\r
1300 {\r
1301         printk("---rda_5990_sleep_worker_task end");\r
1302         wake_unlock(&rda_5990_wake_lock);\r
1303 }\r
1304 \r
1305 void rda_5990_set_wake_lock(void)\r
1306 {\r
1307         wake_lock(&rda_5990_wake_lock);\r
1308         cancel_delayed_work(&rda_5990_sleep_worker);\r
1309         schedule_delayed_work(&rda_5990_sleep_worker, 6*HZ);\r
1310 }\r
1311 \r
1312 int rda_5990_power_ctrl_init(void)\r
1313 {\r
1314         int ret = 0;\r
1315 \r
1316         printk("rda_5990_power_ctrl_init begin\n");\r
1317 \r
1318         rda_5990_major = register_chrdev(0, "rda5990_power_ctrl", &rda_5990_operations);\r
1319         if(rda_5990_major < 0)\r
1320         {\r
1321                 printk(KERN_INFO "register rdabt_power_ctrl failed!!! \n");\r
1322                 return rda_5990_major;\r
1323         }\r
1324 \r
1325         rda_5990_class = class_create(THIS_MODULE, "rda_combo");\r
1326         if(IS_ERR(rda_5990_class))\r
1327         {\r
1328                 unregister_chrdev(rda_5990_major, "rdabt_power_ctrl");\r
1329                 return PTR_ERR(rda_5990_class);\r
1330         }\r
1331 \r
1332         device_create(rda_5990_class, NULL, MKDEV(rda_5990_major, 0), NULL, "rdacombo");\r
1333 \r
1334 \r
1335         INIT_DELAYED_WORK(&rda_5990_sleep_worker, rda_5990_sleep_worker_task);\r
1336         wake_lock_init(&rda_5990_wake_lock, WAKE_LOCK_SUSPEND, "RDA_sleep_worker_wake_lock");\r
1337 \r
1338     mutex_init(&i2c_rw_lock);    \r
1339         printk("rda_5990_power_ctrl_init end\n");\r
1340         return 0;\r
1341 }\r
1342 \r
1343 void rda_5990_power_ctrl_exit(void)\r
1344 {\r
1345 \r
1346         unregister_chrdev(rda_5990_major, "rdabt_power_ctrl");\r
1347         if(rda_5990_class)\r
1348                 class_destroy(rda_5990_class);       \r
1349 \r
1350         cancel_delayed_work_sync(&rda_5990_sleep_worker);\r
1351         wake_lock_destroy(&rda_5990_wake_lock);\r
1352 }\r
1353 \r
1354 unsigned char rda_5990_wifi_in_test_mode(void)\r
1355 {\r
1356         return wifi_in_test_mode;\r
1357 }\r
1358 \r
1359 \r
1360 static __inline__ void cfmakeraw(struct termios *s)\r
1361 {\r
1362         s->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);\r
1363         s->c_oflag &= ~OPOST;\r
1364         s->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);\r
1365         s->c_cflag &= ~(CSIZE|PARENB);\r
1366         s->c_cflag |= CS8;\r
1367 }\r
1368 \r
1369 static __inline__ int cfsetospeed(struct termios *s, speed_t  speed)\r
1370 {\r
1371         s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);\r
1372         return 0;\r
1373 }\r
1374 \r
1375 static __inline__ int cfsetispeed(struct termios *s, speed_t  speed)\r
1376 {\r
1377         s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);\r
1378         return 0;\r
1379 }\r
1380 \r
1381 static int rda_wifi_init_uart(char *dev)\r
1382 {\r
1383         int errno;\r
1384         struct termios ti;\r
1385         struct serial_struct ss;\r
1386         int fd;\r
1387 \r
1388         fd = sys_open(dev, O_RDWR | O_NOCTTY, 0);\r
1389         if (fd < 0) {\r
1390                 printk("Can't open serial port");\r
1391                 return -1;\r
1392         }\r
1393 \r
1394         sys_ioctl(fd, TCFLSH, TCIOFLUSH);\r
1395 \r
1396         /* Clear the cust flag */\r
1397         if((errno = sys_ioctl(fd, TIOCGSERIAL, &ss))<0){\r
1398                 printk("BAUD: error to get the serial_struct info:%s\n", errno);\r
1399                 goto err;\r
1400         }\r
1401 \r
1402         if (ss.flags & ASYNC_SPD_CUST) {\r
1403                 printk("clear ASYNC_SPD_CUST\r\n");\r
1404                 ss.flags &= ~ASYNC_SPD_CUST;\r
1405         }\r
1406         if((errno = sys_ioctl(fd, TIOCSSERIAL, &ss))<0){\r
1407                 printk("BAUD: error to set serial_struct:%s\n", errno);\r
1408                 goto err;\r
1409         }\r
1410 \r
1411         if ((errno = sys_ioctl(fd, TCGETS, (long)&ti))  < 0) {\r
1412                 printk("unable to get UART port setting");\r
1413                 printk("Can't get port settings");\r
1414                 goto err;\r
1415         }\r
1416 \r
1417         cfmakeraw(&ti);\r
1418 \r
1419         ti.c_cflag |= CLOCAL;\r
1420         ti.c_cflag &= ~CRTSCTS;\r
1421         ti.c_lflag = 0;\r
1422         ti.c_cc[VTIME]    = 5; /* 0.5 sec */\r
1423         ti.c_cc[VMIN]     = 0;\r
1424 \r
1425         /* Set initial baudrate */\r
1426         cfsetospeed(&ti, B115200);\r
1427         cfsetispeed(&ti, B115200);\r
1428 \r
1429         if ((errno = sys_ioctl(fd, TCSETS, (long)&ti)) < 0) {\r
1430                 printk("unable to set UART port setting");\r
1431                 printk("Can't set port settings");\r
1432                 goto err;\r
1433         }\r
1434 \r
1435         errno = sys_ioctl(fd, TCFLSH, TCIOFLUSH);\r
1436         if(errno < 0)\r
1437                 goto err;\r
1438 \r
1439         return fd;\r
1440 \r
1441 err:\r
1442         if(fd > 0)\r
1443                 sys_close(fd);\r
1444 \r
1445         return -1;\r
1446 }  \r
1447 \r
1448 EXPORT_SYMBOL(rda_wlan_version);\r
1449 EXPORT_SYMBOL(rda_wifi_init_uart);\r
1450 EXPORT_SYMBOL(rda_5990_wifi_in_test_mode);\r
1451 \r
1452 EXPORT_SYMBOL(rda_5990_set_wake_lock);\r
1453 EXPORT_SYMBOL(rda_wifi_power_off);\r
1454 EXPORT_SYMBOL(rda_wifi_power_on);\r
1455 EXPORT_SYMBOL(rda_fm_power_on);\r
1456 EXPORT_SYMBOL(rda_fm_power_off);\r
1457 \r
1458 module_init(rda_5990_power_ctrl_init);\r
1459 module_exit(rda_5990_power_ctrl_exit);\r
1460 \r
1461 MODULE_LICENSE("GPL");\r
1462 \r