85ea624d7ef487ebb6e50b90635f95b62ecae592
[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_BCMWIFI;
100     } else if (strcmp(wifi_chip_type_string, "rtkwifi") == 0) {
101         type = WIFI_RTKWIFI;
102     } else if (strcmp(wifi_chip_type_string, "esp8089") == 0) {
103         type = WIFI_ESP8089;
104     } else {
105         type = WIFI_BCMWIFI;
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() || cpu_is_rk312x())
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, int irq_type);
440 int rockchip_wifi_set_carddetect(int val)
441 {
442         int chip, irq_type;
443         chip = get_wifi_chip_type();
444
445         /*  irq_type : 0, oob; 1, cap-sdio-irq */
446         if (chip == WIFI_BCMWIFI)
447                 irq_type = 0;
448         else
449                 irq_type = 1;
450
451         return mmc_host_rescan(NULL, val, irq_type);//NULL => SDIO host
452 }
453 EXPORT_SYMBOL(rockchip_wifi_set_carddetect);
454
455 /**************************************************************************
456  *
457  * Wifi Get Interrupt irq Func
458  *
459  *************************************************************************/
460 int rockchip_wifi_get_oob_irq(void)
461 {
462     struct rfkill_wlan_data *mrfkill = g_rfkill;
463     struct rksdmmc_gpio *wifi_int_irq;
464
465     LOG("%s: Enter\n", __func__);
466
467     if (mrfkill == NULL) {
468         LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
469         return -1;
470     }
471     
472     wifi_int_irq = &mrfkill->pdata->wifi_int_b;
473     if (gpio_is_valid(wifi_int_irq->io)) {
474         return gpio_to_irq(wifi_int_irq->io);
475         //return wifi_int_irq->io;
476     } else {
477         LOG("%s: wifi OOB pin isn't defined.\n", __func__);
478     }
479     
480     return -1;
481 }
482 EXPORT_SYMBOL(rockchip_wifi_get_oob_irq);
483
484 /**************************************************************************
485  *
486  * Wifi Reset Func
487  *
488  *************************************************************************/
489 int rockchip_wifi_reset(int on)
490 {
491     return 0;
492 }
493 EXPORT_SYMBOL(rockchip_wifi_reset);
494
495 /**************************************************************************
496  *
497  * Wifi MAC custom Func
498  *
499  *************************************************************************/
500 #include <linux/etherdevice.h>
501 u8 wifi_custom_mac_addr[6] = {0,0,0,0,0,0};
502 extern char GetSNSectorInfo(char * pbuf);
503 int rockchip_wifi_mac_addr(unsigned char *buf)
504 {
505     return -1;
506 /*
507     char mac_buf[20] = {0};
508     LOG("%s: enter.\n", __func__);
509
510     // from vflash
511     if(is_zero_ether_addr(wifi_custom_mac_addr)) {
512         int i;
513         char *tempBuf = kmalloc(512, GFP_KERNEL);
514         if(tempBuf) {
515             GetSNSectorInfo(tempBuf);
516             for (i = 506; i <= 511; i++)
517                 wifi_custom_mac_addr[i-506] = tempBuf[i];
518             kfree(tempBuf);
519         } else {
520             return -1;
521         }
522     }
523
524     sprintf(mac_buf,"%02x:%02x:%02x:%02x:%02x:%02x",wifi_custom_mac_addr[0],wifi_custom_mac_addr[1],
525     wifi_custom_mac_addr[2],wifi_custom_mac_addr[3],wifi_custom_mac_addr[4],wifi_custom_mac_addr[5]);
526     LOG("falsh wifi_custom_mac_addr=[%s]\n", mac_buf);
527
528     if (is_valid_ether_addr(wifi_custom_mac_addr)) {
529         if (2 == (wifi_custom_mac_addr[0] & 0x0F)) {
530             LOG("This mac address come into conflict with the address of direct, ignored...\n");
531             return -1;
532         }
533     } else {
534         LOG("This mac address is not valid, ignored...\n");
535         return -1;
536     }
537
538 #if defined(CONFIG_RKWIFI)
539     memcpy(buf, wifi_custom_mac_addr, 6);
540 #else
541     memcpy(buf, mac_buf, strlen(mac_buf));//realtek's wifi use this branch
542 #endif
543     return 0;
544 */
545 }
546 EXPORT_SYMBOL(rockchip_wifi_mac_addr);
547
548 /**************************************************************************
549  *
550  * wifi get country code func
551  *
552  *************************************************************************/
553 struct cntry_locales_custom {
554     char iso_abbrev[4];  /* ISO 3166-1 country abbreviation */
555     char custom_locale[4];   /* Custom firmware locale */
556     int custom_locale_rev;        /* Custom local revisin default -1 */
557 };
558
559 static struct cntry_locales_custom country_cloc;
560
561 void *rockchip_wifi_country_code(char *ccode)
562 {
563     struct cntry_locales_custom *mcloc;
564
565     LOG("%s: set country code [%s]\n", __func__, ccode);
566     mcloc = &country_cloc;
567     memcpy(mcloc->custom_locale, ccode, 4);
568     mcloc->custom_locale_rev = 0;
569
570     return mcloc;
571 }
572 EXPORT_SYMBOL(rockchip_wifi_country_code);
573 /**************************************************************************/
574
575 static int rockchip_wifi_voltage_select(void)
576 {
577     struct rfkill_wlan_data *mrfkill = g_rfkill;
578     int voltage = 0;
579
580     if (mrfkill == NULL) {
581         LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
582         return -1;
583     }
584     voltage = mrfkill->pdata->sdio_vol;
585     if (voltage > 2700 && voltage < 3500) {
586         writel_relaxed(0x00100000, RK_GRF_VIRT+0x380); //3.3
587         LOG("%s: wifi & sdio reference voltage: 3.3V\n", __func__);
588     } else if (voltage  > 1500 && voltage < 1950) {
589         writel_relaxed(0x00100010, RK_GRF_VIRT+0x380); //1.8
590         LOG("%s: wifi & sdio reference voltage: 1.8V\n", __func__);
591     } else {
592         LOG("%s: unsupport wifi & sdio reference voltage!\n", __func__);
593         return -1;
594     }
595
596     return 0;
597 }
598
599 static int rfkill_rk_setup_gpio(struct rksdmmc_gpio *gpio, const char* prefix, const char* name)
600 {
601     if (gpio_is_valid(gpio->io)) {
602         int ret=0;
603         sprintf(gpio->name, "%s_%s", prefix, name);
604         ret = gpio_request(gpio->io, gpio->name);
605         if (ret) {
606             LOG("Failed to get %s gpio.\n", gpio->name);
607             return -1;
608         }
609     }
610
611     return 0;
612 }
613
614 #ifdef CONFIG_OF
615 static int wlan_platdata_parse_dt(struct device *dev,
616                   struct rksdmmc_gpio_wifi_moudle *data)
617 {
618     struct device_node *node = dev->of_node;
619     const char *strings;
620     u32 value;
621     int gpio,ret;
622     enum of_gpio_flags flags;
623
624     if (!node)
625         return -ENODEV;
626
627     memset(data, 0, sizeof(*data));
628
629     ret = of_property_read_string(node, "wifi_chip_type", &strings);
630     if (ret) {
631         LOG("%s: Can not read wifi_chip_type, set default to rkwifi.\n", __func__);
632         strcpy(wifi_chip_type_string, "rkwifi");
633     }
634     strcpy(wifi_chip_type_string, strings);
635     LOG("%s: wifi_chip_type = %s\n", __func__, wifi_chip_type_string);
636
637         if(cpu_is_rk3036() || cpu_is_rk312x()){
638                 /* ret = of_property_read_u32(node, "sdio_vref", &value);
639                 if (ret < 0) {
640                         LOG("%s: Can't get sdio vref.", __func__);
641                         return -1;
642                 }
643                 data->sdio_vol = value;*/
644         }else{
645                 ret = of_property_read_u32(node, "sdio_vref", &value);
646                 if (ret < 0) {
647                         LOG("%s: Can't get sdio vref.", __func__);
648                         return -1;
649                 }
650                 data->sdio_vol = value;
651         }
652
653     if (of_find_property(node, "vref_ctrl_enable", NULL)) {
654         LOG("%s: enable wifi io reference voltage control.\n", __func__);
655         data->vref_ctrl_enble = true;
656         if (of_find_property(node, "vref_ctrl_gpio", NULL)) {
657             gpio = of_get_named_gpio_flags(node, "vref_ctrl_gpio", 0, &flags);
658             if (gpio_is_valid(gpio)){
659                 data->vddio.io = gpio;
660                 data->vddio.enable = (flags == GPIO_ACTIVE_HIGH)? 1:0;
661                 data->ioregulator.power_ctrl_by_pmu = false;
662                 LOG("%s: get property: vref_ctrl_gpio = %d, flags = %d.\n", __func__, gpio, flags);
663             } else {
664                 data->vddio.io = -1;
665                 data->vref_ctrl_enble = false;
666                 LOG("%s: vref_ctrl_gpio defined invalid, disable wifi io reference voltage control.\n", __func__);
667             }
668         } else {
669             data->ioregulator.power_ctrl_by_pmu = true;
670             ret = of_property_read_string(node, "vref_pmu_regulator", &strings);
671             if (ret) {
672                 LOG("%s: Can not read property: vref_pmu_regulator.\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(%s).\n", __func__, strings);
677                 sprintf(data->ioregulator.pmu_regulator, "%s", strings);
678             }
679             ret = of_property_read_u32(node, "vref_pmu_enable_level", &value);
680             if (ret) {
681                 LOG("%s: Can not read property: vref_pmu_enable_level.\n", __func__);
682                 data->vref_ctrl_enble = false;
683                 data->ioregulator.power_ctrl_by_pmu = false;
684             } else {
685                 LOG("%s: wifi io reference voltage controled by pmu(level = %s).\n", __func__, (value == 1)?"HIGH":"LOW");
686                 data->ioregulator.enable = value;
687             }
688         }
689     } else {
690         data->vref_ctrl_enble = false;
691         LOG("%s: disable wifi io reference voltage control.\n", __func__);
692     }
693
694     if (of_find_property(node, "power_ctrl_by_pmu", NULL)) {
695         data->mregulator.power_ctrl_by_pmu = true;
696         ret = of_property_read_string(node, "power_pmu_regulator", &strings);
697         if (ret) {
698             LOG("%s: Can not read property: power_pmu_regulator.\n", __func__);
699             data->mregulator.power_ctrl_by_pmu = false;
700         } else {
701             LOG("%s: wifi power controled by pmu(%s).\n", __func__, strings);
702             sprintf(data->mregulator.pmu_regulator, "%s", strings);
703         }
704         ret = of_property_read_u32(node, "power_pmu_enable_level", &value);
705         if (ret) {
706             LOG("%s: Can not read property: power_pmu_enable_level.\n", __func__);
707             data->mregulator.power_ctrl_by_pmu = false;
708         } else {
709             LOG("%s: wifi power controled by pmu(level = %s).\n", __func__, (value == 1)?"HIGH":"LOW");
710             data->mregulator.enable = value;
711         }
712         } else {
713                 data->mregulator.power_ctrl_by_pmu = false;
714                 LOG("%s: wifi power controled by gpio.\n", __func__);
715         gpio = of_get_named_gpio_flags(node, "WIFI,poweren_gpio", 0, &flags);
716         if (gpio_is_valid(gpio)){
717                         data->power_n.io = gpio;
718                         data->power_n.enable = (flags == GPIO_ACTIVE_HIGH)? 1:0;
719                         LOG("%s: get property: WIFI,poweren_gpio = %d, flags = %d.\n", __func__, gpio, flags);
720         } else data->power_n.io = -1;
721         gpio = of_get_named_gpio_flags(node, "WIFI,reset_gpio", 0, &flags);
722         if (gpio_is_valid(gpio)){
723                         data->reset_n.io = gpio;
724                         data->reset_n.enable = (flags == GPIO_ACTIVE_HIGH)? 1:0;
725                         LOG("%s: get property: WIFI,reset_gpio = %d, flags = %d.\n", __func__, gpio, flags);
726         } else data->reset_n.io = -1;
727         gpio = of_get_named_gpio_flags(node, "WIFI,host_wake_irq", 0, &flags);
728         if (gpio_is_valid(gpio)){
729                         data->wifi_int_b.io = gpio;
730                         data->wifi_int_b.enable = flags;
731                         LOG("%s: get property: WIFI,host_wake_irq = %d, flags = %d.\n", __func__, gpio, flags);
732         } else data->wifi_int_b.io = -1;
733         }
734
735     return 0;
736 }
737 #endif //CONFIG_OF
738
739 #if defined(CONFIG_HAS_EARLYSUSPEND)
740 #include <linux/earlysuspend.h>
741
742 static void wlan_early_suspend(struct early_suspend *h)
743 {
744     LOG("%s :enter\n", __func__);
745
746     return;
747 }
748
749 static void wlan_late_resume(struct early_suspend *h)
750 {
751     LOG("%s :enter\n", __func__);
752
753     return;
754 }
755
756 struct early_suspend wlan_early_suspend {
757     .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20;
758     .suspend = wlan_early_suspend;
759     .resume = wlan_late_resume; 
760 }
761 #endif
762
763 static int rfkill_wlan_probe(struct platform_device *pdev)
764 {
765         struct rfkill_wlan_data *rfkill;
766         struct rksdmmc_gpio_wifi_moudle *pdata = pdev->dev.platform_data;
767         int ret = -1;
768
769     LOG("Enter %s\n", __func__);
770
771         if (!pdata) {
772 #ifdef CONFIG_OF
773         pdata = kzalloc(sizeof(struct rksdmmc_gpio_wifi_moudle), GFP_KERNEL);
774         if (!pdata)
775             return -ENOMEM;
776
777         ret = wlan_platdata_parse_dt(&pdev->dev, pdata);
778         if (ret < 0) {
779 #endif
780                     LOG("%s: No platform data specified\n", __func__);
781             return ret;
782 #ifdef CONFIG_OF
783         }
784 #endif
785         }
786
787         rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
788         if (!rfkill)
789         goto rfkill_alloc_fail;
790
791         rfkill->pdata = pdata;
792     g_rfkill = rfkill;
793
794     LOG("%s: init gpio\n", __func__);
795
796     if (!pdata->mregulator.power_ctrl_by_pmu) {
797         ret = rfkill_rk_setup_gpio(&pdata->power_n, wlan_name, "wlan_poweren");
798         if (ret) goto fail_alloc;
799
800         ret = rfkill_rk_setup_gpio(&pdata->reset_n, wlan_name, "wlan_reset");
801         if (ret) goto fail_alloc;
802     }
803
804     wake_lock_init(&(rfkill->wlan_irq_wl), WAKE_LOCK_SUSPEND, "rfkill_wlan_wake");
805
806     // Turn off wifi power as default
807     if (gpio_is_valid(pdata->power_n.io))
808     {
809         gpio_direction_output(pdata->power_n.io, !pdata->power_n.enable);
810     }
811
812     rockchip_wifi_voltage_select();
813
814 #if BCM_STATIC_MEMORY_SUPPORT
815     rockchip_init_wifi_mem();
816 #endif
817
818 #if defined(CONFIG_HAS_EARLYSUSPEND)
819     register_early_suspend(wlan_early_suspend);
820 #endif
821
822     LOG("Exit %s\n", __func__);
823
824         return 0;
825
826 fail_alloc:
827         kfree(rfkill);
828 rfkill_alloc_fail:
829     kfree(pdata);
830
831     g_rfkill = NULL;
832
833         return ret;
834 }
835
836 static int rfkill_wlan_remove(struct platform_device *pdev)
837 {
838         struct rfkill_wlan_data *rfkill = platform_get_drvdata(pdev);
839
840     LOG("Enter %s\n", __func__);
841
842     wake_lock_destroy(&rfkill->wlan_irq_wl);
843     
844     if (gpio_is_valid(rfkill->pdata->power_n.io))
845         gpio_free(rfkill->pdata->power_n.io);
846     
847     if (gpio_is_valid(rfkill->pdata->reset_n.io))
848         gpio_free(rfkill->pdata->reset_n.io);
849     
850 //    if (gpio_is_valid(rfkill->pdata->vddio.io))
851 //        gpio_free(rfkill->pdata->vddio.io);
852 //
853 //    if (gpio_is_valid(rfkill->pdata->bgf_int_b.io))
854 //        gpio_free(rfkill->pdata->bgf_int_b.io);
855 //    
856 //    if (gpio_is_valid(rfkill->pdata->gps_sync.io))
857 //        gpio_free(rfkill->pdata->gps_sync.io);
858 //    
859 //    if (gpio_is_valid(rfkill->pdata->ANTSEL2.io))
860 //        gpio_free(rfkill->pdata->ANTSEL2.io);
861 //
862 //    if (gpio_is_valid(rfkill->pdata->ANTSEL3.io))
863 //        gpio_free(rfkill->pdata->ANTSEL3.io);
864 //    
865 //    if (gpio_is_valid(rfkill->pdata->GPS_LAN.io))
866 //        gpio_free(rfkill->pdata->GPS_LAN.io);
867
868     kfree(rfkill);
869     g_rfkill = NULL;
870
871         return 0;
872 }
873
874 static int rfkill_wlan_suspend(struct platform_device *pdev, pm_message_t state)
875 {
876     LOG("Enter %s\n", __func__);
877     return 0;
878 }
879
880 static int rfkill_wlan_resume(struct platform_device *pdev)
881 {
882     LOG("Enter %s\n", __func__);
883     return 0;
884 }
885
886 #ifdef CONFIG_OF
887 static struct of_device_id wlan_platdata_of_match[] = {
888     { .compatible = "wlan-platdata" },
889     { }
890 };
891 MODULE_DEVICE_TABLE(of, wlan_platdata_of_match);
892 #endif //CONFIG_OF
893
894 static struct platform_driver rfkill_wlan_driver = {
895         .probe = rfkill_wlan_probe,
896         .remove = rfkill_wlan_remove,
897     .suspend = rfkill_wlan_suspend,
898     .resume = rfkill_wlan_resume,
899         .driver = {
900                 .name = "wlan-platdata",
901                 .owner = THIS_MODULE,
902         .of_match_table = of_match_ptr(wlan_platdata_of_match),
903         },
904 };
905
906 static int __init rfkill_wlan_init(void)
907 {
908     LOG("Enter %s\n", __func__);
909         return platform_driver_register(&rfkill_wlan_driver);
910 }
911
912 static void __exit rfkill_wlan_exit(void)
913 {
914     LOG("Enter %s\n", __func__);
915         platform_driver_unregister(&rfkill_wlan_driver);
916 }
917
918 module_init(rfkill_wlan_init);
919 module_exit(rfkill_wlan_exit);
920
921 MODULE_DESCRIPTION("rock-chips rfkill for wifi v0.1");
922 MODULE_AUTHOR("gwl@rock-chips.com");
923 MODULE_LICENSE("GPL");