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