wifi: build together with rkwifi, esp8089, rtl8188eu driver, avoid config change
[firefly-linux-kernel-4.4.55.git] / net / rfkill / rfkill-wlan.c
1 /*
2  * Copyright (C) 2012 ROCKCHIP, Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  */
14 /* Rock-chips rfkill driver for wifi
15 */
16
17 #include <linux/kernel.h>
18 #include <linux/platform_device.h>
19 #include <linux/module.h>
20 #include <linux/rfkill.h>
21 #include <linux/init.h>
22 #include <linux/slab.h>
23 #include <asm/gpio.h>
24 #include <linux/regulator/consumer.h>
25 #include <linux/delay.h>
26 #include <linux/rfkill-wlan.h>
27 #include <linux/rfkill-bt.h>
28 #include <linux/wakelock.h>
29 #include <linux/interrupt.h>
30 #include <asm/irq.h>
31 #include <linux/suspend.h>
32 #include <linux/proc_fs.h>
33 #include <linux/uaccess.h>
34 #include <linux/gpio.h>
35 #include <linux/rockchip/iomap.h>
36 #include <dt-bindings/gpio/gpio.h>
37 #include <linux/skbuff.h>
38 #include <linux/rockchip/cpu.h>
39 #ifdef CONFIG_OF
40 #include <linux/of.h>
41 #include <linux/of_device.h>
42 #include <linux/of_gpio.h>
43 #endif
44
45 #if 0
46 #define DBG(x...)   printk(KERN_INFO "[WLAN_RFKILL]: "x)
47 #else
48 #define DBG(x...)
49 #endif
50
51 #define LOG(x...)   printk(KERN_INFO "[WLAN_RFKILL]: "x)
52
53 struct rfkill_wlan_data {
54         struct rksdmmc_gpio_wifi_moudle *pdata;
55     struct wake_lock            wlan_irq_wl;
56 };
57
58 static struct rfkill_wlan_data *g_rfkill = NULL;
59
60 static const char wlan_name[] = 
61 #if defined (CONFIG_BCM4330)
62     #if defined (CONFIG_BT_MODULE_NH660)
63         "nh660"
64     #else
65         "bcm4330"
66     #endif
67 #elif defined (CONFIG_RK903)
68     #if defined(CONFIG_RKWIFI_26M)
69         "rk903_26M"
70     #else
71         "rk903"
72     #endif
73 #elif defined(CONFIG_BCM4329)
74         "bcm4329"
75 #elif defined(CONFIG_MV8787)
76         "mv8787"
77 #elif defined(CONFIG_AP6210)
78     #if defined(CONFIG_RKWIFI_26M)
79         "ap6210"
80     #else
81         "ap6210_24M"
82     #endif
83 #elif defined(CONFIG_AP6330)
84                 "ap6330"
85 #elif defined(CONFIG_AP6476)
86                 "ap6476"
87 #elif defined(CONFIG_AP6493)
88                 "ap6493"
89 #else
90         "wlan_default"
91 #endif
92 ;
93
94 static char wifi_chip_type_string[64];
95 int get_wifi_chip_type(void)
96 {
97     int type;
98     if (strcmp(wifi_chip_type_string, "rkwifi") == 0) {
99         type = WIFI_RKWIFI;
100     } else if (strcmp(wifi_chip_type_string, "rtl8188eu") == 0) {
101         type = WIFI_RTL8188EU;
102     } else if (strcmp(wifi_chip_type_string, "esp8089") == 0) {
103         type = WIFI_ESP8089;
104     } else {
105         type = WIFI_RKWIFI;
106     }
107     return type;
108 }
109 EXPORT_SYMBOL(get_wifi_chip_type);
110
111 /***********************************************************
112  * 
113  * Broadcom Wifi Static Memory
114  * 
115  **********************************************************/
116 #ifdef CONFIG_RKWIFI
117 #define BCM_STATIC_MEMORY_SUPPORT 1
118 #else
119 #define BCM_STATIC_MEMORY_SUPPORT 0
120 #endif
121 //===========================
122 #if BCM_STATIC_MEMORY_SUPPORT
123 #define PREALLOC_WLAN_SEC_NUM           4
124 #define PREALLOC_WLAN_BUF_NUM           160
125 #define PREALLOC_WLAN_SECTION_HEADER    0
126 #define WLAN_SKB_BUF_NUM        16
127
128 #define WLAN_SECTION_SIZE_0     (12 * 1024)
129 #define WLAN_SECTION_SIZE_1     (12 * 1024)
130 #define WLAN_SECTION_SIZE_2     (32 * 1024)
131 #define WLAN_SECTION_SIZE_3     (136* 1024)
132 #define WLAN_SECTION_SIZE_4     (4  * 1024)
133 #define WLAN_SECTION_SIZE_5     (64 * 1024)
134 #define WLAN_SECTION_SIZE_6     (4  * 1024)
135 #define WLAN_SECTION_SIZE_7     (4  * 1024)
136
137 static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM+1];
138
139 struct wifi_mem_prealloc {
140     void *mem_ptr;
141     unsigned long size;
142 };
143
144 static struct wifi_mem_prealloc wifi_mem_array[8] = {
145     {NULL, (WLAN_SECTION_SIZE_0)},
146     {NULL, (WLAN_SECTION_SIZE_1)},
147     {NULL, (WLAN_SECTION_SIZE_2)},
148     {NULL, (WLAN_SECTION_SIZE_3)},
149     {NULL, (WLAN_SECTION_SIZE_4)},
150     {NULL, (WLAN_SECTION_SIZE_5)},
151     {NULL, (WLAN_SECTION_SIZE_6)},
152     {NULL, (WLAN_SECTION_SIZE_7)}
153 };
154
155 static int rockchip_init_wifi_mem(void)
156 {
157     int i;
158     int j;
159
160     for (i = 0 ; i < WLAN_SKB_BUF_NUM ; i++) {
161         wlan_static_skb[i] = dev_alloc_skb(
162                ((i < (WLAN_SKB_BUF_NUM / 2)) ? (PAGE_SIZE*1) : (PAGE_SIZE*2)));
163
164         if (!wlan_static_skb[i])
165             goto err_skb_alloc;
166     }
167
168     wlan_static_skb[i] = dev_alloc_skb((PAGE_SIZE*4));
169     if (!wlan_static_skb[i])
170         goto err_skb_alloc;
171
172     for (i = 0 ; i <= 7; i++) {
173         wifi_mem_array[i].mem_ptr =
174                kmalloc(wifi_mem_array[i].size, GFP_KERNEL);
175
176         if (!wifi_mem_array[i].mem_ptr)
177             goto err_mem_alloc;
178     }
179     return 0;
180
181 err_mem_alloc:
182     pr_err("Failed to mem_alloc for WLAN\n");
183     for (j = 0 ; j < i ; j++)
184         kfree(wifi_mem_array[j].mem_ptr);
185     i = WLAN_SKB_BUF_NUM;
186 err_skb_alloc:
187     pr_err("Failed to skb_alloc for WLAN\n");
188     for (j = 0 ; j < i ; j++)
189         dev_kfree_skb(wlan_static_skb[j]);
190     dev_kfree_skb(wlan_static_skb[j]);
191
192     return -ENOMEM;
193 }
194
195 void *rockchip_mem_prealloc(int section, unsigned long size)
196 {
197     //printk("rockchip_mem_prealloc: section = %d, size = %d\n", section, size);
198     if (section == PREALLOC_WLAN_SEC_NUM)
199         return wlan_static_skb;
200
201     if ((section < 0) || (section > 7))
202         return NULL;
203
204     if (wifi_mem_array[section].size < size)
205         return NULL;
206
207     return wifi_mem_array[section].mem_ptr;
208 }
209 #else
210 void *rockchip_mem_prealloc(int section, unsigned long size) { return NULL;}
211 #endif
212 EXPORT_SYMBOL(rockchip_mem_prealloc);
213
214 /**************************************************************************
215  *
216  * get wifi power state Func
217  *
218  *************************************************************************/
219 static int wifi_power_state = 0;
220 int rfkill_get_wifi_power_state(int *power, int *vref_ctrl_enable)
221 {
222     struct rfkill_wlan_data *mrfkill = g_rfkill;
223
224     if (mrfkill == NULL) {
225         LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
226         return -1;
227     }
228
229     if (mrfkill->pdata->vref_ctrl_enble)
230         *vref_ctrl_enable = 1;
231     *power = wifi_power_state;
232
233     return 0;
234 }
235
236 /**************************************************************************
237  *
238  * wifi reference voltage control Func
239  *
240  *************************************************************************/
241 int rockchip_wifi_ref_voltage(int on)
242 {
243     struct rfkill_wlan_data *mrfkill = g_rfkill;
244     struct rksdmmc_gpio *vddio;
245     struct regulator *ldo = NULL;
246     int power = 0;
247     bool toggle = false;
248
249     LOG("%s: %d\n", __func__, on);
250
251     if (mrfkill == NULL) {
252         LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
253         return -1;
254     }
255
256     if (!mrfkill->pdata->vref_ctrl_enble) {
257         LOG("%s: wifi io reference voltage control is disabled.\n", __func__);
258         return 0;
259     }
260
261     if (!rfkill_get_bt_power_state(&power, &toggle)) {
262         if (power == 1) {
263             LOG("%s: wifi shouldn't control io reference voltage, BT is running!\n", __func__);
264             return 0;
265         }
266     }
267
268     if (mrfkill->pdata->ioregulator.power_ctrl_by_pmu) {
269         int ret = -1;
270         char *ldostr;
271         int level = mrfkill->pdata->ioregulator.enable;
272                 int voltage = 1000 * mrfkill->pdata->sdio_vol;
273
274         ldostr = mrfkill->pdata->ioregulator.pmu_regulator;
275         if (ldostr == NULL) {
276             LOG("%s: wifi io reference voltage set to be controled by pmic, but which one?\n", __func__);
277             return -1;
278         }
279         ldo = regulator_get(NULL, ldostr);
280         if (ldo == NULL || IS_ERR(ldo)) {
281             LOG("\n\n\n%s get ldo error,please mod this\n\n\n", __func__);
282             return -1;
283         } else {
284             if (on == level) {
285                 if(cpu_is_rk3036())
286                 {
287                                         /*regulator_set_voltage(ldo, voltage, voltage);
288                                         LOG("%s: %s enabled, level = %d\n", __func__, ldostr, voltage);
289                                         ret = regulator_enable(ldo);
290                                         LOG("wifi turn on io reference voltage.\n");*/
291                 }else{
292                                         regulator_set_voltage(ldo, voltage, voltage);
293                                         LOG("%s: %s enabled, level = %d\n", __func__, ldostr, voltage);
294                                         ret = regulator_enable(ldo);
295                                         LOG("wifi turn on io reference voltage.\n");
296                 }
297             } else {
298                 LOG("%s: %s disabled\n", __func__, ldostr);
299                 while (regulator_is_enabled(ldo) > 0) {
300                     ret = regulator_disable(ldo);
301                 }
302                 LOG("wifi shut off io reference voltage.\n");
303             }
304             regulator_put(ldo);
305             msleep(100);
306         }
307     } else {
308         vddio = &mrfkill->pdata->power_n;
309
310         if (on){
311             if (gpio_is_valid(vddio->io)) {
312                 gpio_set_value(vddio->io, vddio->enable);
313                 msleep(100);
314             }
315
316             LOG("wifi turn on io reference voltage.\n");
317         }else{
318             if (gpio_is_valid(vddio->io)) {
319                 gpio_set_value(vddio->io, !(vddio->enable));
320                 msleep(100);
321             }
322
323             LOG("wifi shut off io reference voltage.\n");
324         }
325     }
326
327         return 0;
328 }
329
330 /**************************************************************************
331  *
332  * Wifi Power Control Func
333  * 0 -> power off
334  * 1 -> power on
335  *
336  *************************************************************************/
337 int rockchip_wifi_power(int on)
338 {
339         struct rfkill_wlan_data *mrfkill = g_rfkill;
340     struct rksdmmc_gpio *poweron, *reset;
341     struct regulator *ldo = NULL;
342     int power = 0;
343     bool toggle = false;
344
345     LOG("%s: %d\n", __func__, on);
346
347     if (mrfkill == NULL) {
348         LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
349         return -1;
350     }
351
352     if (!rfkill_get_bt_power_state(&power, &toggle)) {
353         if (toggle == true && power == 1) {
354             LOG("%s: wifi shouldn't control the power, it was enabled by BT!\n", __func__);
355             return 0;
356         }
357     }
358     
359     if (on)
360         rockchip_wifi_ref_voltage(1);
361
362     if (mrfkill->pdata->mregulator.power_ctrl_by_pmu) {
363         int ret = -1;
364         char *ldostr;
365         int level = mrfkill->pdata->mregulator.enable;
366
367         ldostr = mrfkill->pdata->mregulator.pmu_regulator;
368         if (ldostr == NULL) {
369             LOG("%s: wifi power set to be controled by pmic, but which one?\n", __func__);
370             return -1;
371         }
372         ldo = regulator_get(NULL, ldostr);
373         if (ldo == NULL || IS_ERR(ldo)) {
374             LOG("\n\n\n%s get ldo error,please mod this\n\n\n", __func__);
375             return -1;
376         } else {
377                         if (on == level) {
378                                 regulator_set_voltage(ldo, 3000000, 3000000);
379                             LOG("%s: %s enabled\n", __func__, ldostr);
380                                 ret = regulator_enable(ldo);
381                 wifi_power_state = 1;
382                             LOG("wifi turn on power.\n");
383             } else {
384                                 LOG("%s: %s disabled\n", __func__, ldostr);
385                 while (regulator_is_enabled(ldo) > 0) {
386                                     ret = regulator_disable(ldo);
387                 }
388                 wifi_power_state = 0;
389                             LOG("wifi shut off power.\n");
390                         }
391                         regulator_put(ldo);
392                         msleep(100);
393                 }
394     } else {
395                 poweron = &mrfkill->pdata->power_n;
396                 reset = &mrfkill->pdata->reset_n;
397
398                 if (on){
399                         if (gpio_is_valid(poweron->io)) {
400                                 gpio_set_value(poweron->io, poweron->enable);
401                                 msleep(100);
402                         }
403
404                         if (gpio_is_valid(reset->io)) {
405                                 gpio_set_value(reset->io, reset->enable);
406                                 msleep(100);
407                         }
408
409             wifi_power_state = 1;
410                         LOG("wifi turn on power. %d\n", poweron->io);
411                 }else{
412                         if (gpio_is_valid(poweron->io)) {
413                                 gpio_set_value(poweron->io, !(poweron->enable));
414                                 msleep(100);
415                         }
416
417                         if (gpio_is_valid(reset->io)) {
418                                 gpio_set_value(reset->io, !(reset->enable));
419                         }
420
421             wifi_power_state = 0;
422                         LOG("wifi shut off power.\n");
423                 }
424     }
425
426     if (!on)
427         rockchip_wifi_ref_voltage(0);
428
429     return 0;
430 }
431 EXPORT_SYMBOL(rockchip_wifi_power);
432
433 /**************************************************************************
434  *
435  * Wifi Sdio Detect Func
436  *
437  *************************************************************************/
438 #include <linux/mmc/host.h>
439 extern int mmc_host_rescan(struct mmc_host *host, int val);
440 int rockchip_wifi_set_carddetect(int val)
441 {
442     return mmc_host_rescan(NULL, val);//NULL => SDIO host
443 }
444 EXPORT_SYMBOL(rockchip_wifi_set_carddetect);
445
446 /**************************************************************************
447  *
448  * Wifi Get Interrupt irq Func
449  *
450  *************************************************************************/
451 int rockchip_wifi_get_oob_irq(void)
452 {
453     struct rfkill_wlan_data *mrfkill = g_rfkill;
454     struct rksdmmc_gpio *wifi_int_irq;
455
456     LOG("%s: Enter\n", __func__);
457
458     if (mrfkill == NULL) {
459         LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
460         return -1;
461     }
462     
463     wifi_int_irq = &mrfkill->pdata->wifi_int_b;
464     if (gpio_is_valid(wifi_int_irq->io)) {
465         return gpio_to_irq(wifi_int_irq->io);
466         //return wifi_int_irq->io;
467     } else {
468         LOG("%s: wifi OOB pin isn't defined.\n", __func__);
469     }
470     
471     return -1;
472 }
473 EXPORT_SYMBOL(rockchip_wifi_get_oob_irq);
474
475 /**************************************************************************
476  *
477  * Wifi Reset Func
478  *
479  *************************************************************************/
480 int rockchip_wifi_reset(int on)
481 {
482     return 0;
483 }
484 EXPORT_SYMBOL(rockchip_wifi_reset);
485
486 /**************************************************************************
487  *
488  * Wifi MAC custom Func
489  *
490  *************************************************************************/
491 #include <linux/etherdevice.h>
492 u8 wifi_custom_mac_addr[6] = {0,0,0,0,0,0};
493 extern char GetSNSectorInfo(char * pbuf);
494 int rockchip_wifi_mac_addr(unsigned char *buf)
495 {
496     return -1;
497 /*
498     char mac_buf[20] = {0};
499     LOG("%s: enter.\n", __func__);
500
501     // from vflash
502     if(is_zero_ether_addr(wifi_custom_mac_addr)) {
503         int i;
504         char *tempBuf = kmalloc(512, GFP_KERNEL);
505         if(tempBuf) {
506             GetSNSectorInfo(tempBuf);
507             for (i = 506; i <= 511; i++)
508                 wifi_custom_mac_addr[i-506] = tempBuf[i];
509             kfree(tempBuf);
510         } else {
511             return -1;
512         }
513     }
514
515     sprintf(mac_buf,"%02x:%02x:%02x:%02x:%02x:%02x",wifi_custom_mac_addr[0],wifi_custom_mac_addr[1],
516     wifi_custom_mac_addr[2],wifi_custom_mac_addr[3],wifi_custom_mac_addr[4],wifi_custom_mac_addr[5]);
517     LOG("falsh wifi_custom_mac_addr=[%s]\n", mac_buf);
518
519     if (is_valid_ether_addr(wifi_custom_mac_addr)) {
520         if (2 == (wifi_custom_mac_addr[0] & 0x0F)) {
521             LOG("This mac address come into conflict with the address of direct, ignored...\n");
522             return -1;
523         }
524     } else {
525         LOG("This mac address is not valid, ignored...\n");
526         return -1;
527     }
528
529 #if defined(CONFIG_RKWIFI)
530     memcpy(buf, wifi_custom_mac_addr, 6);
531 #else
532     memcpy(buf, mac_buf, strlen(mac_buf));//realtek's wifi use this branch
533 #endif
534     return 0;
535 */
536 }
537 EXPORT_SYMBOL(rockchip_wifi_mac_addr);
538
539 /**************************************************************************
540  *
541  * wifi get country code func
542  *
543  *************************************************************************/
544 struct cntry_locales_custom {
545     char iso_abbrev[4];  /* ISO 3166-1 country abbreviation */
546     char custom_locale[4];   /* Custom firmware locale */
547     int custom_locale_rev;        /* Custom local revisin default -1 */
548 };
549
550 static struct cntry_locales_custom country_cloc;
551
552 void *rockchip_wifi_country_code(char *ccode)
553 {
554     struct cntry_locales_custom *mcloc;
555
556     LOG("%s: set country code [%s]\n", __func__, ccode);
557     mcloc = &country_cloc;
558     memcpy(mcloc->custom_locale, ccode, 4);
559     mcloc->custom_locale_rev = 0;
560
561     return mcloc;
562 }
563 EXPORT_SYMBOL(rockchip_wifi_country_code);
564 /**************************************************************************/
565
566 static int rockchip_wifi_voltage_select(void)
567 {
568     struct rfkill_wlan_data *mrfkill = g_rfkill;
569     int voltage = 0;
570
571     if (mrfkill == NULL) {
572         LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
573         return -1;
574     }
575     voltage = mrfkill->pdata->sdio_vol;
576     if (voltage > 2700 && voltage < 3500) {
577         writel_relaxed(0x00100000, RK_GRF_VIRT+0x380); //3.3
578         LOG("%s: wifi & sdio reference voltage: 3.3V\n", __func__);
579     } else if (voltage  > 1500 && voltage < 1950) {
580         writel_relaxed(0x00100010, RK_GRF_VIRT+0x380); //1.8
581         LOG("%s: wifi & sdio reference voltage: 1.8V\n", __func__);
582     } else {
583         LOG("%s: unsupport wifi & sdio reference voltage!\n", __func__);
584         return -1;
585     }
586
587     return 0;
588 }
589
590 static int rfkill_rk_setup_gpio(struct rksdmmc_gpio *gpio, const char* prefix, const char* name)
591 {
592     if (gpio_is_valid(gpio->io)) {
593         int ret=0;
594         sprintf(gpio->name, "%s_%s", prefix, name);
595         ret = gpio_request(gpio->io, gpio->name);
596         if (ret) {
597             LOG("Failed to get %s gpio.\n", gpio->name);
598             return -1;
599         }
600     }
601
602     return 0;
603 }
604
605 #ifdef CONFIG_OF
606 static int wlan_platdata_parse_dt(struct device *dev,
607                   struct rksdmmc_gpio_wifi_moudle *data)
608 {
609     struct device_node *node = dev->of_node;
610     const char *strings;
611     u32 value;
612     int gpio,ret;
613     enum of_gpio_flags flags;
614
615     if (!node)
616         return -ENODEV;
617
618     memset(data, 0, sizeof(*data));
619
620     ret = of_property_read_string(node, "wifi_chip_type", &strings);
621     if (ret) {
622         printk("%s: Can not read wifi_chip_type, set default to rkwifi.\n", __func__);
623         strcpy(wifi_chip_type_string, "rkwifi");
624     }
625     strcpy(wifi_chip_type_string, strings);
626     printk("%s: wifi_chip_type = %s\n", __func__, wifi_chip_type_string);
627
628         if(cpu_is_rk3036()){
629                 /* ret = of_property_read_u32(node, "sdio_vref", &value);
630                 if (ret < 0) {
631                         LOG("%s: Can't get sdio vref.", __func__);
632                         return -1;
633                 }
634                 data->sdio_vol = value;*/
635         }else{
636                 ret = of_property_read_u32(node, "sdio_vref", &value);
637                 if (ret < 0) {
638                         LOG("%s: Can't get sdio vref.", __func__);
639                         return -1;
640                 }
641                 data->sdio_vol = value;
642         }
643
644     if (of_find_property(node, "vref_ctrl_enable", NULL)) {
645         LOG("%s: enable wifi io reference voltage control.\n", __func__);
646         data->vref_ctrl_enble = true;
647         if (of_find_property(node, "vref_ctrl_gpio", NULL)) {
648             gpio = of_get_named_gpio_flags(node, "vref_ctrl_gpio", 0, &flags);
649             if (gpio_is_valid(gpio)){
650                 data->vddio.io = gpio;
651                 data->vddio.enable = (flags == GPIO_ACTIVE_HIGH)? 1:0;
652                 data->ioregulator.power_ctrl_by_pmu = false;
653                 LOG("%s: get property: vref_ctrl_gpio = %d, flags = %d.\n", __func__, gpio, flags);
654             } else {
655                 data->vddio.io = -1;
656                 data->vref_ctrl_enble = false;
657                 LOG("%s: vref_ctrl_gpio defined invalid, disable wifi io reference voltage control.\n", __func__);
658             }
659         } else {
660             data->ioregulator.power_ctrl_by_pmu = true;
661             ret = of_property_read_string(node, "vref_pmu_regulator", &strings);
662             if (ret) {
663                 LOG("%s: Can not read property: vref_pmu_regulator.\n", __func__);
664                 data->vref_ctrl_enble = false;
665                 data->ioregulator.power_ctrl_by_pmu = false;
666             } else {
667                 LOG("%s: wifi io reference voltage controled by pmu(%s).\n", __func__, strings);
668                 sprintf(data->ioregulator.pmu_regulator, "%s", strings);
669             }
670             ret = of_property_read_u32(node, "vref_pmu_enable_level", &value);
671             if (ret) {
672                 LOG("%s: Can not read property: vref_pmu_enable_level.\n", __func__);
673                 data->vref_ctrl_enble = false;
674                 data->ioregulator.power_ctrl_by_pmu = false;
675             } else {
676                 LOG("%s: wifi io reference voltage controled by pmu(level = %s).\n", __func__, (value == 1)?"HIGH":"LOW");
677                 data->ioregulator.enable = value;
678             }
679         }
680     } else {
681         data->vref_ctrl_enble = false;
682         LOG("%s: disable wifi io reference voltage control.\n", __func__);
683     }
684
685     if (of_find_property(node, "power_ctrl_by_pmu", NULL)) {
686         data->mregulator.power_ctrl_by_pmu = true;
687         ret = of_property_read_string(node, "power_pmu_regulator", &strings);
688         if (ret) {
689             LOG("%s: Can not read property: power_pmu_regulator.\n", __func__);
690             data->mregulator.power_ctrl_by_pmu = false;
691         } else {
692             LOG("%s: wifi power controled by pmu(%s).\n", __func__, strings);
693             sprintf(data->mregulator.pmu_regulator, "%s", strings);
694         }
695         ret = of_property_read_u32(node, "power_pmu_enable_level", &value);
696         if (ret) {
697             LOG("%s: Can not read property: power_pmu_enable_level.\n", __func__);
698             data->mregulator.power_ctrl_by_pmu = false;
699         } else {
700             LOG("%s: wifi power controled by pmu(level = %s).\n", __func__, (value == 1)?"HIGH":"LOW");
701             data->mregulator.enable = value;
702         }
703         } else {
704                 data->mregulator.power_ctrl_by_pmu = false;
705                 LOG("%s: wifi power controled by gpio.\n", __func__);
706         gpio = of_get_named_gpio_flags(node, "WIFI,poweren_gpio", 0, &flags);
707         if (gpio_is_valid(gpio)){
708                         data->power_n.io = gpio;
709                         data->power_n.enable = (flags == GPIO_ACTIVE_HIGH)? 1:0;
710                         LOG("%s: get property: WIFI,poweren_gpio = %d, flags = %d.\n", __func__, gpio, flags);
711         } else data->power_n.io = -1;
712         gpio = of_get_named_gpio_flags(node, "WIFI,reset_gpio", 0, &flags);
713         if (gpio_is_valid(gpio)){
714                         data->reset_n.io = gpio;
715                         data->reset_n.enable = (flags == GPIO_ACTIVE_HIGH)? 1:0;
716                         LOG("%s: get property: WIFI,reset_gpio = %d, flags = %d.\n", __func__, gpio, flags);
717         } else data->reset_n.io = -1;
718         gpio = of_get_named_gpio_flags(node, "WIFI,host_wake_irq", 0, &flags);
719         if (gpio_is_valid(gpio)){
720                         data->wifi_int_b.io = gpio;
721                         data->wifi_int_b.enable = flags;
722                         LOG("%s: get property: WIFI,host_wake_irq = %d, flags = %d.\n", __func__, gpio, flags);
723         } else data->wifi_int_b.io = -1;
724         }
725
726     return 0;
727 }
728 #endif //CONFIG_OF
729
730 #if defined(CONFIG_HAS_EARLYSUSPEND)
731 #include <linux/earlysuspend.h>
732
733 static void wlan_early_suspend(struct early_suspend *h)
734 {
735     LOG("%s :enter\n", __func__);
736
737     return;
738 }
739
740 static void wlan_late_resume(struct early_suspend *h)
741 {
742     LOG("%s :enter\n", __func__);
743
744     return;
745 }
746
747 struct early_suspend wlan_early_suspend {
748     .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20;
749     .suspend = wlan_early_suspend;
750     .resume = wlan_late_resume; 
751 }
752 #endif
753
754 static int rfkill_wlan_probe(struct platform_device *pdev)
755 {
756         struct rfkill_wlan_data *rfkill;
757         struct rksdmmc_gpio_wifi_moudle *pdata = pdev->dev.platform_data;
758         int ret = -1;
759
760     LOG("Enter %s\n", __func__);
761
762         if (!pdata) {
763 #ifdef CONFIG_OF
764         pdata = kzalloc(sizeof(struct rksdmmc_gpio_wifi_moudle), GFP_KERNEL);
765         if (!pdata)
766             return -ENOMEM;
767
768         ret = wlan_platdata_parse_dt(&pdev->dev, pdata);
769         if (ret < 0) {
770 #endif
771                     LOG("%s: No platform data specified\n", __func__);
772             return ret;
773 #ifdef CONFIG_OF
774         }
775 #endif
776         }
777
778         rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
779         if (!rfkill)
780         goto rfkill_alloc_fail;
781
782         rfkill->pdata = pdata;
783     g_rfkill = rfkill;
784
785     LOG("%s: init gpio\n", __func__);
786
787     if (!pdata->mregulator.power_ctrl_by_pmu) {
788         ret = rfkill_rk_setup_gpio(&pdata->power_n, wlan_name, "wlan_poweren");
789         if (ret) goto fail_alloc;
790
791         ret = rfkill_rk_setup_gpio(&pdata->reset_n, wlan_name, "wlan_reset");
792         if (ret) goto fail_alloc;
793     }
794
795     wake_lock_init(&(rfkill->wlan_irq_wl), WAKE_LOCK_SUSPEND, "rfkill_wlan_wake");
796
797     // Turn off wifi power as default
798     if (gpio_is_valid(pdata->power_n.io))
799     {
800         gpio_direction_output(pdata->power_n.io, !pdata->power_n.enable);
801     }
802
803     rockchip_wifi_voltage_select();
804
805 #if BCM_STATIC_MEMORY_SUPPORT
806     rockchip_init_wifi_mem();
807 #endif
808
809 #if defined(CONFIG_HAS_EARLYSUSPEND)
810     register_early_suspend(wlan_early_suspend);
811 #endif
812
813     LOG("Exit %s\n", __func__);
814
815         return 0;
816
817 fail_alloc:
818         kfree(rfkill);
819 rfkill_alloc_fail:
820     kfree(pdata);
821
822     g_rfkill = NULL;
823
824         return ret;
825 }
826
827 static int rfkill_wlan_remove(struct platform_device *pdev)
828 {
829         struct rfkill_wlan_data *rfkill = platform_get_drvdata(pdev);
830
831     LOG("Enter %s\n", __func__);
832
833     wake_lock_destroy(&rfkill->wlan_irq_wl);
834     
835     if (gpio_is_valid(rfkill->pdata->power_n.io))
836         gpio_free(rfkill->pdata->power_n.io);
837     
838     if (gpio_is_valid(rfkill->pdata->reset_n.io))
839         gpio_free(rfkill->pdata->reset_n.io);
840     
841 //    if (gpio_is_valid(rfkill->pdata->vddio.io))
842 //        gpio_free(rfkill->pdata->vddio.io);
843 //
844 //    if (gpio_is_valid(rfkill->pdata->bgf_int_b.io))
845 //        gpio_free(rfkill->pdata->bgf_int_b.io);
846 //    
847 //    if (gpio_is_valid(rfkill->pdata->gps_sync.io))
848 //        gpio_free(rfkill->pdata->gps_sync.io);
849 //    
850 //    if (gpio_is_valid(rfkill->pdata->ANTSEL2.io))
851 //        gpio_free(rfkill->pdata->ANTSEL2.io);
852 //
853 //    if (gpio_is_valid(rfkill->pdata->ANTSEL3.io))
854 //        gpio_free(rfkill->pdata->ANTSEL3.io);
855 //    
856 //    if (gpio_is_valid(rfkill->pdata->GPS_LAN.io))
857 //        gpio_free(rfkill->pdata->GPS_LAN.io);
858
859     kfree(rfkill);
860     g_rfkill = NULL;
861
862         return 0;
863 }
864
865 static int rfkill_wlan_suspend(struct platform_device *pdev, pm_message_t state)
866 {
867     LOG("Enter %s\n", __func__);
868     return 0;
869 }
870
871 static int rfkill_wlan_resume(struct platform_device *pdev)
872 {
873     LOG("Enter %s\n", __func__);
874     return 0;
875 }
876
877 #ifdef CONFIG_OF
878 static struct of_device_id wlan_platdata_of_match[] = {
879     { .compatible = "wlan-platdata" },
880     { }
881 };
882 MODULE_DEVICE_TABLE(of, wlan_platdata_of_match);
883 #endif //CONFIG_OF
884
885 static struct platform_driver rfkill_wlan_driver = {
886         .probe = rfkill_wlan_probe,
887         .remove = rfkill_wlan_remove,
888     .suspend = rfkill_wlan_suspend,
889     .resume = rfkill_wlan_resume,
890         .driver = {
891                 .name = "wlan-platdata",
892                 .owner = THIS_MODULE,
893         .of_match_table = of_match_ptr(wlan_platdata_of_match),
894         },
895 };
896
897 static int __init rfkill_wlan_init(void)
898 {
899     LOG("Enter %s\n", __func__);
900         return platform_driver_register(&rfkill_wlan_driver);
901 }
902
903 static void __exit rfkill_wlan_exit(void)
904 {
905     LOG("Enter %s\n", __func__);
906         platform_driver_unregister(&rfkill_wlan_driver);
907 }
908
909 module_init(rfkill_wlan_init);
910 module_exit(rfkill_wlan_exit);
911
912 MODULE_DESCRIPTION("rock-chips rfkill for wifi v0.1");
913 MODULE_AUTHOR("gwl@rock-chips.com");
914 MODULE_LICENSE("GPL");