2 * Copyright (C) 2012 ROCKCHIP, Inc.
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.
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.
14 /* Rock-chips rfkill driver for wifi
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>
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>
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>
41 #include <linux/of_device.h>
42 #include <linux/of_gpio.h>
46 #define DBG(x...) printk(KERN_INFO "[WLAN_RFKILL]: "x)
51 #define LOG(x...) printk(KERN_INFO "[WLAN_RFKILL]: "x)
53 struct rfkill_wlan_data {
54 struct rksdmmc_gpio_wifi_moudle *pdata;
55 struct wake_lock wlan_irq_wl;
58 static struct rfkill_wlan_data *g_rfkill = NULL;
60 static const char wlan_name[] =
61 #if defined (CONFIG_BCM4330)
62 #if defined (CONFIG_BT_MODULE_NH660)
67 #elif defined (CONFIG_RK903)
68 #if defined(CONFIG_RKWIFI_26M)
73 #elif defined(CONFIG_BCM4329)
75 #elif defined(CONFIG_MV8787)
77 #elif defined(CONFIG_AP6210)
78 #if defined(CONFIG_RKWIFI_26M)
83 #elif defined(CONFIG_AP6330)
85 #elif defined(CONFIG_AP6476)
87 #elif defined(CONFIG_AP6493)
94 static char wifi_chip_type_string[64];
95 int get_wifi_chip_type(void)
98 if (strcmp(wifi_chip_type_string, "rkwifi") == 0) {
100 } else if (strcmp(wifi_chip_type_string, "rtl8188eu") == 0) {
101 type = WIFI_RTL8188EU;
102 } else if (strcmp(wifi_chip_type_string, "esp8089") == 0) {
104 } else if (strcmp(wifi_chip_type_string, "rtl8723bs") == 0) {
105 type = WIFI_RTL8723BS;
111 EXPORT_SYMBOL(get_wifi_chip_type);
113 /***********************************************************
115 * Broadcom Wifi Static Memory
117 **********************************************************/
119 #define BCM_STATIC_MEMORY_SUPPORT 1
121 #define BCM_STATIC_MEMORY_SUPPORT 0
123 //===========================
124 #if BCM_STATIC_MEMORY_SUPPORT
125 #define PREALLOC_WLAN_SEC_NUM 4
126 #define PREALLOC_WLAN_BUF_NUM 160
127 #define PREALLOC_WLAN_SECTION_HEADER 0
128 #define WLAN_SKB_BUF_NUM 16
130 #define WLAN_SECTION_SIZE_0 (12 * 1024)
131 #define WLAN_SECTION_SIZE_1 (12 * 1024)
132 #define WLAN_SECTION_SIZE_2 (32 * 1024)
133 #define WLAN_SECTION_SIZE_3 (136* 1024)
134 #define WLAN_SECTION_SIZE_4 (4 * 1024)
135 #define WLAN_SECTION_SIZE_5 (64 * 1024)
136 #define WLAN_SECTION_SIZE_6 (4 * 1024)
137 #define WLAN_SECTION_SIZE_7 (4 * 1024)
139 static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM+1];
141 struct wifi_mem_prealloc {
146 static struct wifi_mem_prealloc wifi_mem_array[8] = {
147 {NULL, (WLAN_SECTION_SIZE_0)},
148 {NULL, (WLAN_SECTION_SIZE_1)},
149 {NULL, (WLAN_SECTION_SIZE_2)},
150 {NULL, (WLAN_SECTION_SIZE_3)},
151 {NULL, (WLAN_SECTION_SIZE_4)},
152 {NULL, (WLAN_SECTION_SIZE_5)},
153 {NULL, (WLAN_SECTION_SIZE_6)},
154 {NULL, (WLAN_SECTION_SIZE_7)}
157 static int rockchip_init_wifi_mem(void)
162 for (i = 0 ; i < WLAN_SKB_BUF_NUM ; i++) {
163 wlan_static_skb[i] = dev_alloc_skb(
164 ((i < (WLAN_SKB_BUF_NUM / 2)) ? (PAGE_SIZE*1) : (PAGE_SIZE*2)));
166 if (!wlan_static_skb[i])
170 wlan_static_skb[i] = dev_alloc_skb((PAGE_SIZE*4));
171 if (!wlan_static_skb[i])
174 for (i = 0 ; i <= 7; i++) {
175 wifi_mem_array[i].mem_ptr =
176 kmalloc(wifi_mem_array[i].size, GFP_KERNEL);
178 if (!wifi_mem_array[i].mem_ptr)
184 pr_err("Failed to mem_alloc for WLAN\n");
185 for (j = 0 ; j < i ; j++)
186 kfree(wifi_mem_array[j].mem_ptr);
187 i = WLAN_SKB_BUF_NUM;
189 pr_err("Failed to skb_alloc for WLAN\n");
190 for (j = 0 ; j < i ; j++)
191 dev_kfree_skb(wlan_static_skb[j]);
192 dev_kfree_skb(wlan_static_skb[j]);
197 void *rockchip_mem_prealloc(int section, unsigned long size)
199 //printk("rockchip_mem_prealloc: section = %d, size = %d\n", section, size);
200 if (section == PREALLOC_WLAN_SEC_NUM)
201 return wlan_static_skb;
203 if ((section < 0) || (section > 7))
206 if (wifi_mem_array[section].size < size)
209 return wifi_mem_array[section].mem_ptr;
212 void *rockchip_mem_prealloc(int section, unsigned long size) { return NULL;}
214 EXPORT_SYMBOL(rockchip_mem_prealloc);
216 /**************************************************************************
218 * get wifi power state Func
220 *************************************************************************/
221 static int wifi_power_state = 0;
222 int rfkill_get_wifi_power_state(int *power, int *vref_ctrl_enable)
224 struct rfkill_wlan_data *mrfkill = g_rfkill;
226 if (mrfkill == NULL) {
227 LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
231 if (mrfkill->pdata->vref_ctrl_enble)
232 *vref_ctrl_enable = 1;
233 *power = wifi_power_state;
238 /**************************************************************************
240 * wifi reference voltage control Func
242 *************************************************************************/
243 int rockchip_wifi_ref_voltage(int on)
245 struct rfkill_wlan_data *mrfkill = g_rfkill;
246 struct rksdmmc_gpio *vddio;
247 struct regulator *ldo = NULL;
251 LOG("%s: %d\n", __func__, on);
253 if (mrfkill == NULL) {
254 LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
258 if (!mrfkill->pdata->vref_ctrl_enble) {
259 LOG("%s: wifi io reference voltage control is disabled.\n", __func__);
263 if (!rfkill_get_bt_power_state(&power, &toggle)) {
265 LOG("%s: wifi shouldn't control io reference voltage, BT is running!\n", __func__);
270 if (mrfkill->pdata->ioregulator.power_ctrl_by_pmu) {
273 int level = mrfkill->pdata->ioregulator.enable;
274 int voltage = 1000 * mrfkill->pdata->sdio_vol;
276 ldostr = mrfkill->pdata->ioregulator.pmu_regulator;
277 if (ldostr == NULL) {
278 LOG("%s: wifi io reference voltage set to be controled by pmic, but which one?\n", __func__);
281 ldo = regulator_get(NULL, ldostr);
282 if (ldo == NULL || IS_ERR(ldo)) {
283 LOG("\n\n\n%s get ldo error,please mod this\n\n\n", __func__);
287 if(cpu_is_rk3036() || cpu_is_rk312x())
289 /*regulator_set_voltage(ldo, voltage, voltage);
290 LOG("%s: %s enabled, level = %d\n", __func__, ldostr, voltage);
291 ret = regulator_enable(ldo);
292 LOG("wifi turn on io reference voltage.\n");*/
294 regulator_set_voltage(ldo, voltage, voltage);
295 LOG("%s: %s enabled, level = %d\n", __func__, ldostr, voltage);
296 ret = regulator_enable(ldo);
297 LOG("wifi turn on io reference voltage.\n");
300 LOG("%s: %s disabled\n", __func__, ldostr);
301 while (regulator_is_enabled(ldo) > 0) {
302 ret = regulator_disable(ldo);
304 LOG("wifi shut off io reference voltage.\n");
310 vddio = &mrfkill->pdata->power_n;
313 if (gpio_is_valid(vddio->io)) {
314 gpio_set_value(vddio->io, vddio->enable);
318 LOG("wifi turn on io reference voltage.\n");
320 if (gpio_is_valid(vddio->io)) {
321 gpio_set_value(vddio->io, !(vddio->enable));
325 LOG("wifi shut off io reference voltage.\n");
332 /**************************************************************************
334 * Wifi Power Control Func
338 *************************************************************************/
339 int rockchip_wifi_power(int on)
341 struct rfkill_wlan_data *mrfkill = g_rfkill;
342 struct rksdmmc_gpio *poweron, *reset;
343 struct regulator *ldo = NULL;
347 LOG("%s: %d\n", __func__, on);
349 if (mrfkill == NULL) {
350 LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
354 if (!rfkill_get_bt_power_state(&power, &toggle)) {
355 if (toggle == true && power == 1) {
356 LOG("%s: wifi shouldn't control the power, it was enabled by BT!\n", __func__);
362 rockchip_wifi_ref_voltage(1);
364 if (mrfkill->pdata->mregulator.power_ctrl_by_pmu) {
367 int level = mrfkill->pdata->mregulator.enable;
369 ldostr = mrfkill->pdata->mregulator.pmu_regulator;
370 if (ldostr == NULL) {
371 LOG("%s: wifi power set to be controled by pmic, but which one?\n", __func__);
374 ldo = regulator_get(NULL, ldostr);
375 if (ldo == NULL || IS_ERR(ldo)) {
376 LOG("\n\n\n%s get ldo error,please mod this\n\n\n", __func__);
380 regulator_set_voltage(ldo, 3000000, 3000000);
381 LOG("%s: %s enabled\n", __func__, ldostr);
382 ret = regulator_enable(ldo);
383 wifi_power_state = 1;
384 LOG("wifi turn on power.\n");
386 LOG("%s: %s disabled\n", __func__, ldostr);
387 while (regulator_is_enabled(ldo) > 0) {
388 ret = regulator_disable(ldo);
390 wifi_power_state = 0;
391 LOG("wifi shut off power.\n");
397 poweron = &mrfkill->pdata->power_n;
398 reset = &mrfkill->pdata->reset_n;
401 if (gpio_is_valid(poweron->io)) {
402 gpio_set_value(poweron->io, poweron->enable);
406 if (gpio_is_valid(reset->io)) {
407 gpio_set_value(reset->io, reset->enable);
411 wifi_power_state = 1;
412 LOG("wifi turn on power. %d\n", poweron->io);
414 if (gpio_is_valid(poweron->io)) {
415 gpio_set_value(poweron->io, !(poweron->enable));
419 if (gpio_is_valid(reset->io)) {
420 gpio_set_value(reset->io, !(reset->enable));
423 wifi_power_state = 0;
424 LOG("wifi shut off power.\n");
429 rockchip_wifi_ref_voltage(0);
433 EXPORT_SYMBOL(rockchip_wifi_power);
435 /**************************************************************************
437 * Wifi Sdio Detect Func
439 *************************************************************************/
440 #include <linux/mmc/host.h>
441 extern int mmc_host_rescan(struct mmc_host *host, int val, int irq_type);
442 int rockchip_wifi_set_carddetect(int val)
445 chip = get_wifi_chip_type();
447 /* irq_type : 0, oob; 1, cap-sdio-irq */
448 if (chip == WIFI_RKWIFI)
453 return mmc_host_rescan(NULL, val, irq_type);//NULL => SDIO host
455 EXPORT_SYMBOL(rockchip_wifi_set_carddetect);
457 /**************************************************************************
459 * Wifi Get Interrupt irq Func
461 *************************************************************************/
462 int rockchip_wifi_get_oob_irq(void)
464 struct rfkill_wlan_data *mrfkill = g_rfkill;
465 struct rksdmmc_gpio *wifi_int_irq;
467 LOG("%s: Enter\n", __func__);
469 if (mrfkill == NULL) {
470 LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
474 wifi_int_irq = &mrfkill->pdata->wifi_int_b;
475 if (gpio_is_valid(wifi_int_irq->io)) {
476 return gpio_to_irq(wifi_int_irq->io);
477 //return wifi_int_irq->io;
479 LOG("%s: wifi OOB pin isn't defined.\n", __func__);
484 EXPORT_SYMBOL(rockchip_wifi_get_oob_irq);
486 /**************************************************************************
490 *************************************************************************/
491 int rockchip_wifi_reset(int on)
495 EXPORT_SYMBOL(rockchip_wifi_reset);
497 /**************************************************************************
499 * Wifi MAC custom Func
501 *************************************************************************/
502 #include <linux/etherdevice.h>
503 u8 wifi_custom_mac_addr[6] = {0,0,0,0,0,0};
504 extern char GetSNSectorInfo(char * pbuf);
505 int rockchip_wifi_mac_addr(unsigned char *buf)
509 char mac_buf[20] = {0};
510 LOG("%s: enter.\n", __func__);
513 if(is_zero_ether_addr(wifi_custom_mac_addr)) {
515 char *tempBuf = kmalloc(512, GFP_KERNEL);
517 GetSNSectorInfo(tempBuf);
518 for (i = 506; i <= 511; i++)
519 wifi_custom_mac_addr[i-506] = tempBuf[i];
526 sprintf(mac_buf,"%02x:%02x:%02x:%02x:%02x:%02x",wifi_custom_mac_addr[0],wifi_custom_mac_addr[1],
527 wifi_custom_mac_addr[2],wifi_custom_mac_addr[3],wifi_custom_mac_addr[4],wifi_custom_mac_addr[5]);
528 LOG("falsh wifi_custom_mac_addr=[%s]\n", mac_buf);
530 if (is_valid_ether_addr(wifi_custom_mac_addr)) {
531 if (2 == (wifi_custom_mac_addr[0] & 0x0F)) {
532 LOG("This mac address come into conflict with the address of direct, ignored...\n");
536 LOG("This mac address is not valid, ignored...\n");
540 #if defined(CONFIG_RKWIFI)
541 memcpy(buf, wifi_custom_mac_addr, 6);
543 memcpy(buf, mac_buf, strlen(mac_buf));//realtek's wifi use this branch
548 EXPORT_SYMBOL(rockchip_wifi_mac_addr);
550 /**************************************************************************
552 * wifi get country code func
554 *************************************************************************/
555 struct cntry_locales_custom {
556 char iso_abbrev[4]; /* ISO 3166-1 country abbreviation */
557 char custom_locale[4]; /* Custom firmware locale */
558 int custom_locale_rev; /* Custom local revisin default -1 */
561 static struct cntry_locales_custom country_cloc;
563 void *rockchip_wifi_country_code(char *ccode)
565 struct cntry_locales_custom *mcloc;
567 LOG("%s: set country code [%s]\n", __func__, ccode);
568 mcloc = &country_cloc;
569 memcpy(mcloc->custom_locale, ccode, 4);
570 mcloc->custom_locale_rev = 0;
574 EXPORT_SYMBOL(rockchip_wifi_country_code);
575 /**************************************************************************/
577 static int rockchip_wifi_voltage_select(void)
579 struct rfkill_wlan_data *mrfkill = g_rfkill;
582 if (mrfkill == NULL) {
583 LOG("%s: rfkill-wlan driver has not Successful initialized\n", __func__);
586 voltage = mrfkill->pdata->sdio_vol;
587 if (voltage > 2700 && voltage < 3500) {
588 writel_relaxed(0x00100000, RK_GRF_VIRT+0x380); //3.3
589 LOG("%s: wifi & sdio reference voltage: 3.3V\n", __func__);
590 } else if (voltage > 1500 && voltage < 1950) {
591 writel_relaxed(0x00100010, RK_GRF_VIRT+0x380); //1.8
592 LOG("%s: wifi & sdio reference voltage: 1.8V\n", __func__);
594 LOG("%s: unsupport wifi & sdio reference voltage!\n", __func__);
601 static int rfkill_rk_setup_gpio(struct rksdmmc_gpio *gpio, const char* prefix, const char* name)
603 if (gpio_is_valid(gpio->io)) {
605 sprintf(gpio->name, "%s_%s", prefix, name);
606 ret = gpio_request(gpio->io, gpio->name);
608 LOG("Failed to get %s gpio.\n", gpio->name);
617 static int wlan_platdata_parse_dt(struct device *dev,
618 struct rksdmmc_gpio_wifi_moudle *data)
620 struct device_node *node = dev->of_node;
624 enum of_gpio_flags flags;
629 memset(data, 0, sizeof(*data));
631 ret = of_property_read_string(node, "wifi_chip_type", &strings);
633 printk("%s: Can not read wifi_chip_type, set default to rkwifi.\n", __func__);
634 strcpy(wifi_chip_type_string, "rkwifi");
636 strcpy(wifi_chip_type_string, strings);
637 printk("%s: wifi_chip_type = %s\n", __func__, wifi_chip_type_string);
639 if(cpu_is_rk3036() || cpu_is_rk312x()){
640 /* ret = of_property_read_u32(node, "sdio_vref", &value);
642 LOG("%s: Can't get sdio vref.", __func__);
645 data->sdio_vol = value;*/
647 ret = of_property_read_u32(node, "sdio_vref", &value);
649 LOG("%s: Can't get sdio vref.", __func__);
652 data->sdio_vol = value;
655 if (of_find_property(node, "vref_ctrl_enable", NULL)) {
656 LOG("%s: enable wifi io reference voltage control.\n", __func__);
657 data->vref_ctrl_enble = true;
658 if (of_find_property(node, "vref_ctrl_gpio", NULL)) {
659 gpio = of_get_named_gpio_flags(node, "vref_ctrl_gpio", 0, &flags);
660 if (gpio_is_valid(gpio)){
661 data->vddio.io = gpio;
662 data->vddio.enable = (flags == GPIO_ACTIVE_HIGH)? 1:0;
663 data->ioregulator.power_ctrl_by_pmu = false;
664 LOG("%s: get property: vref_ctrl_gpio = %d, flags = %d.\n", __func__, gpio, flags);
667 data->vref_ctrl_enble = false;
668 LOG("%s: vref_ctrl_gpio defined invalid, disable wifi io reference voltage control.\n", __func__);
671 data->ioregulator.power_ctrl_by_pmu = true;
672 ret = of_property_read_string(node, "vref_pmu_regulator", &strings);
674 LOG("%s: Can not read property: vref_pmu_regulator.\n", __func__);
675 data->vref_ctrl_enble = false;
676 data->ioregulator.power_ctrl_by_pmu = false;
678 LOG("%s: wifi io reference voltage controled by pmu(%s).\n", __func__, strings);
679 sprintf(data->ioregulator.pmu_regulator, "%s", strings);
681 ret = of_property_read_u32(node, "vref_pmu_enable_level", &value);
683 LOG("%s: Can not read property: vref_pmu_enable_level.\n", __func__);
684 data->vref_ctrl_enble = false;
685 data->ioregulator.power_ctrl_by_pmu = false;
687 LOG("%s: wifi io reference voltage controled by pmu(level = %s).\n", __func__, (value == 1)?"HIGH":"LOW");
688 data->ioregulator.enable = value;
692 data->vref_ctrl_enble = false;
693 LOG("%s: disable wifi io reference voltage control.\n", __func__);
696 if (of_find_property(node, "power_ctrl_by_pmu", NULL)) {
697 data->mregulator.power_ctrl_by_pmu = true;
698 ret = of_property_read_string(node, "power_pmu_regulator", &strings);
700 LOG("%s: Can not read property: power_pmu_regulator.\n", __func__);
701 data->mregulator.power_ctrl_by_pmu = false;
703 LOG("%s: wifi power controled by pmu(%s).\n", __func__, strings);
704 sprintf(data->mregulator.pmu_regulator, "%s", strings);
706 ret = of_property_read_u32(node, "power_pmu_enable_level", &value);
708 LOG("%s: Can not read property: power_pmu_enable_level.\n", __func__);
709 data->mregulator.power_ctrl_by_pmu = false;
711 LOG("%s: wifi power controled by pmu(level = %s).\n", __func__, (value == 1)?"HIGH":"LOW");
712 data->mregulator.enable = value;
715 data->mregulator.power_ctrl_by_pmu = false;
716 LOG("%s: wifi power controled by gpio.\n", __func__);
717 gpio = of_get_named_gpio_flags(node, "WIFI,poweren_gpio", 0, &flags);
718 if (gpio_is_valid(gpio)){
719 data->power_n.io = gpio;
720 data->power_n.enable = (flags == GPIO_ACTIVE_HIGH)? 1:0;
721 LOG("%s: get property: WIFI,poweren_gpio = %d, flags = %d.\n", __func__, gpio, flags);
722 } else data->power_n.io = -1;
723 gpio = of_get_named_gpio_flags(node, "WIFI,reset_gpio", 0, &flags);
724 if (gpio_is_valid(gpio)){
725 data->reset_n.io = gpio;
726 data->reset_n.enable = (flags == GPIO_ACTIVE_HIGH)? 1:0;
727 LOG("%s: get property: WIFI,reset_gpio = %d, flags = %d.\n", __func__, gpio, flags);
728 } else data->reset_n.io = -1;
729 gpio = of_get_named_gpio_flags(node, "WIFI,host_wake_irq", 0, &flags);
730 if (gpio_is_valid(gpio)){
731 data->wifi_int_b.io = gpio;
732 data->wifi_int_b.enable = flags;
733 LOG("%s: get property: WIFI,host_wake_irq = %d, flags = %d.\n", __func__, gpio, flags);
734 } else data->wifi_int_b.io = -1;
741 #if defined(CONFIG_HAS_EARLYSUSPEND)
742 #include <linux/earlysuspend.h>
744 static void wlan_early_suspend(struct early_suspend *h)
746 LOG("%s :enter\n", __func__);
751 static void wlan_late_resume(struct early_suspend *h)
753 LOG("%s :enter\n", __func__);
758 struct early_suspend wlan_early_suspend {
759 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20;
760 .suspend = wlan_early_suspend;
761 .resume = wlan_late_resume;
765 static int rfkill_wlan_probe(struct platform_device *pdev)
767 struct rfkill_wlan_data *rfkill;
768 struct rksdmmc_gpio_wifi_moudle *pdata = pdev->dev.platform_data;
771 LOG("Enter %s\n", __func__);
775 pdata = kzalloc(sizeof(struct rksdmmc_gpio_wifi_moudle), GFP_KERNEL);
779 ret = wlan_platdata_parse_dt(&pdev->dev, pdata);
782 LOG("%s: No platform data specified\n", __func__);
789 rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
791 goto rfkill_alloc_fail;
793 rfkill->pdata = pdata;
796 LOG("%s: init gpio\n", __func__);
798 if (!pdata->mregulator.power_ctrl_by_pmu) {
799 ret = rfkill_rk_setup_gpio(&pdata->power_n, wlan_name, "wlan_poweren");
800 if (ret) goto fail_alloc;
802 ret = rfkill_rk_setup_gpio(&pdata->reset_n, wlan_name, "wlan_reset");
803 if (ret) goto fail_alloc;
806 wake_lock_init(&(rfkill->wlan_irq_wl), WAKE_LOCK_SUSPEND, "rfkill_wlan_wake");
808 // Turn off wifi power as default
809 if (gpio_is_valid(pdata->power_n.io))
811 gpio_direction_output(pdata->power_n.io, !pdata->power_n.enable);
814 rockchip_wifi_voltage_select();
816 #if BCM_STATIC_MEMORY_SUPPORT
817 rockchip_init_wifi_mem();
820 #if defined(CONFIG_HAS_EARLYSUSPEND)
821 register_early_suspend(wlan_early_suspend);
824 LOG("Exit %s\n", __func__);
838 static int rfkill_wlan_remove(struct platform_device *pdev)
840 struct rfkill_wlan_data *rfkill = platform_get_drvdata(pdev);
842 LOG("Enter %s\n", __func__);
844 wake_lock_destroy(&rfkill->wlan_irq_wl);
846 if (gpio_is_valid(rfkill->pdata->power_n.io))
847 gpio_free(rfkill->pdata->power_n.io);
849 if (gpio_is_valid(rfkill->pdata->reset_n.io))
850 gpio_free(rfkill->pdata->reset_n.io);
852 // if (gpio_is_valid(rfkill->pdata->vddio.io))
853 // gpio_free(rfkill->pdata->vddio.io);
855 // if (gpio_is_valid(rfkill->pdata->bgf_int_b.io))
856 // gpio_free(rfkill->pdata->bgf_int_b.io);
858 // if (gpio_is_valid(rfkill->pdata->gps_sync.io))
859 // gpio_free(rfkill->pdata->gps_sync.io);
861 // if (gpio_is_valid(rfkill->pdata->ANTSEL2.io))
862 // gpio_free(rfkill->pdata->ANTSEL2.io);
864 // if (gpio_is_valid(rfkill->pdata->ANTSEL3.io))
865 // gpio_free(rfkill->pdata->ANTSEL3.io);
867 // if (gpio_is_valid(rfkill->pdata->GPS_LAN.io))
868 // gpio_free(rfkill->pdata->GPS_LAN.io);
876 static int rfkill_wlan_suspend(struct platform_device *pdev, pm_message_t state)
878 LOG("Enter %s\n", __func__);
882 static int rfkill_wlan_resume(struct platform_device *pdev)
884 LOG("Enter %s\n", __func__);
889 static struct of_device_id wlan_platdata_of_match[] = {
890 { .compatible = "wlan-platdata" },
893 MODULE_DEVICE_TABLE(of, wlan_platdata_of_match);
896 static struct platform_driver rfkill_wlan_driver = {
897 .probe = rfkill_wlan_probe,
898 .remove = rfkill_wlan_remove,
899 .suspend = rfkill_wlan_suspend,
900 .resume = rfkill_wlan_resume,
902 .name = "wlan-platdata",
903 .owner = THIS_MODULE,
904 .of_match_table = of_match_ptr(wlan_platdata_of_match),
908 static int __init rfkill_wlan_init(void)
910 LOG("Enter %s\n", __func__);
911 return platform_driver_register(&rfkill_wlan_driver);
914 static void __exit rfkill_wlan_exit(void)
916 LOG("Enter %s\n", __func__);
917 platform_driver_unregister(&rfkill_wlan_driver);
920 module_init(rfkill_wlan_init);
921 module_exit(rfkill_wlan_exit);
923 MODULE_DESCRIPTION("rock-chips rfkill for wifi v0.1");
924 MODULE_AUTHOR("gwl@rock-chips.com");
925 MODULE_LICENSE("GPL");