1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <drv_types.h>
24 #include <platform_ops.h>
26 #ifndef CONFIG_SDIO_HCI
27 #error "CONFIG_SDIO_HCI shall be on!\n"
30 #ifdef CONFIG_PLATFORM_INTEL_BYT
32 #include <linux/acpi.h>
33 #include <linux/acpi_gpio.h>
34 #include "rtw_android.h"
36 static int wlan_en_gpio = -1;
37 #endif //CONFIG_PLATFORM_INTEL_BYT
39 #ifndef dev_to_sdio_func
40 #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev)
44 static struct mmc_host *mmc_host = NULL;
47 static const struct sdio_device_id sdio_ids[] =
49 #ifdef CONFIG_RTL8723B
50 { SDIO_DEVICE(0x024c, 0xB723),.driver_data = RTL8723B},
52 #ifdef CONFIG_RTL8188E
53 { SDIO_DEVICE(0x024c, 0x8179),.driver_data = RTL8188E},
54 #endif //CONFIG_RTL8188E
56 #ifdef CONFIG_RTL8821A
57 { SDIO_DEVICE(0x024c, 0x8821),.driver_data = RTL8821},
58 #endif //CONFIG_RTL8821A
60 #ifdef CONFIG_RTL8192E
61 { SDIO_DEVICE(0x024c, 0x818B),.driver_data = RTL8192E},
62 #endif //CONFIG_RTL8192E
64 #ifdef CONFIG_RTL8703B
65 { SDIO_DEVICE(0x024c, 0xB703), .driver_data = RTL8703B},
68 #ifdef CONFIG_RTL8188F
69 {SDIO_DEVICE(0x024c, 0xF179), .driver_data = RTL8188F},
72 #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) /* temporarily add this to accept all sdio wlan id */
73 { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) },
75 { /* end: all zeroes */ },
78 MODULE_DEVICE_TABLE(sdio, sdio_ids);
80 static int rtw_drv_init(struct sdio_func *func, const struct sdio_device_id *id);
81 static void rtw_dev_remove(struct sdio_func *func);
82 static int rtw_sdio_resume(struct device *dev);
83 static int rtw_sdio_suspend(struct device *dev);
84 extern void rtw_dev_unload(PADAPTER padapter);
86 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
87 static const struct dev_pm_ops rtw_sdio_pm_ops = {
88 .suspend = rtw_sdio_suspend,
89 .resume = rtw_sdio_resume,
93 struct sdio_drv_priv {
94 struct sdio_driver r871xs_drv;
98 static struct sdio_drv_priv sdio_drvpriv = {
99 .r871xs_drv.probe = rtw_drv_init,
100 .r871xs_drv.remove = rtw_dev_remove,
101 .r871xs_drv.name = (char*)DRV_NAME,
102 .r871xs_drv.id_table = sdio_ids,
103 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
105 .pm = &rtw_sdio_pm_ops,
110 static void sd_sync_int_hdl(struct sdio_func *func)
112 struct dvobj_priv *psdpriv;
114 psdpriv = sdio_get_drvdata(func);
116 if (!psdpriv->padapters[IFACE_ID0]) {
117 DBG_871X("%s if1 == NULL\n", __func__);
121 rtw_sdio_set_irq_thd(psdpriv, current);
122 sd_int_hdl(psdpriv->padapters[IFACE_ID0]);
123 rtw_sdio_set_irq_thd(psdpriv, NULL);
126 int sdio_alloc_irq(struct dvobj_priv *dvobj)
128 PSDIO_DATA psdio_data;
129 struct sdio_func *func;
132 psdio_data = &dvobj->intf_data;
133 func = psdio_data->func;
135 sdio_claim_host(func);
137 err = sdio_claim_irq(func, &sd_sync_int_hdl);
140 dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++;
141 printk(KERN_CRIT "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err);
145 dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++;
146 dvobj->irq_alloc = 1;
149 sdio_release_host(func);
151 return err?_FAIL:_SUCCESS;
154 void sdio_free_irq(struct dvobj_priv *dvobj)
156 PSDIO_DATA psdio_data;
157 struct sdio_func *func;
160 if (dvobj->irq_alloc) {
161 psdio_data = &dvobj->intf_data;
162 func = psdio_data->func;
165 sdio_claim_host(func);
166 err = sdio_release_irq(func);
169 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
170 DBG_871X_LEVEL(_drv_err_,"%s: sdio_release_irq FAIL(%d)!\n", __func__, err);
173 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
174 sdio_release_host(func);
176 dvobj->irq_alloc = 0;
180 #ifdef CONFIG_GPIO_WAKEUP
181 extern unsigned int oob_irq;
182 extern unsigned int oob_gpio;
183 static irqreturn_t gpio_hostwakeup_irq_thread(int irq, void *data)
185 PADAPTER padapter = (PADAPTER)data;
186 DBG_871X_LEVEL(_drv_always_, "gpio_hostwakeup_irq_thread\n");
187 /* Disable interrupt before calling handler */
188 //disable_irq_nosync(oob_irq);
189 rtw_lock_suspend_timeout(HZ/2);
190 #ifdef CONFIG_PLATFORM_ARM_SUN6I
197 static u8 gpio_hostwakeup_alloc_irq(PADAPTER padapter)
203 DBG_871X("oob_irq ZERO!\n");
207 DBG_871X("%s : oob_irq = %d\n", __func__, oob_irq);
209 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
210 status = IRQF_NO_SUSPEND;
214 status |= IRQF_TRIGGER_RISING;
216 status |= IRQF_TRIGGER_FALLING;
218 err = request_threaded_irq(oob_irq, gpio_hostwakeup_irq_thread, NULL,
219 status, "rtw_wifi_gpio_wakeup", padapter);
222 DBG_871X("Oops: can't allocate gpio irq %d err:%d\n", oob_irq, err);
225 DBG_871X("allocate gpio irq %d ok\n", oob_irq);
228 #ifndef CONFIG_PLATFORM_ARM_SUN8I
229 enable_irq_wake(oob_irq);
234 static void gpio_hostwakeup_free_irq(PADAPTER padapter)
236 wifi_free_gpio(oob_gpio);
241 #ifndef CONFIG_PLATFORM_ARM_SUN8I
242 disable_irq_wake(oob_irq);
244 free_irq(oob_irq, padapter);
248 static u32 sdio_init(struct dvobj_priv *dvobj)
250 PSDIO_DATA psdio_data;
251 struct sdio_func *func;
256 psdio_data = &dvobj->intf_data;
257 func = psdio_data->func;
260 sdio_claim_host(func);
262 err = sdio_enable_func(func);
264 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
265 DBG_8192C(KERN_CRIT "%s: sdio_enable_func FAIL(%d)!\n", __func__, err);
269 err = sdio_set_block_size(func, 512);
271 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
272 DBG_8192C(KERN_CRIT "%s: sdio_set_block_size FAIL(%d)!\n", __func__, err);
275 psdio_data->block_transfer_len = 512;
276 psdio_data->tx_block_mode = 1;
277 psdio_data->rx_block_mode = 1;
280 sdio_release_host(func);
285 if (err) return _FAIL;
289 static void sdio_deinit(struct dvobj_priv *dvobj)
291 struct sdio_func *func;
295 RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+sdio_deinit\n"));
297 func = dvobj->intf_data.func;
300 sdio_claim_host(func);
301 err = sdio_disable_func(func);
304 dvobj->drv_dbg.dbg_sdio_deinit_error_cnt++;
305 DBG_8192C(KERN_ERR "%s: sdio_disable_func(%d)\n", __func__, err);
308 if (dvobj->irq_alloc) {
309 err = sdio_release_irq(func);
312 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
313 DBG_8192C(KERN_ERR "%s: sdio_release_irq(%d)\n", __func__, err);
316 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
319 sdio_release_host(func);
323 static void rtw_decide_chip_type_by_device_id(struct dvobj_priv *dvobj, const struct sdio_device_id *pdid)
325 dvobj->chip_type = pdid->driver_data;
327 #if defined(CONFIG_RTL8188E)
328 if (dvobj->chip_type == RTL8188E) {
329 dvobj->HardwareType = HARDWARE_TYPE_RTL8188ES;
330 DBG_871X("CHIP TYPE: RTL8188E\n");
334 #if defined(CONFIG_RTL8723B)
335 dvobj->chip_type = RTL8723B;
336 dvobj->HardwareType = HARDWARE_TYPE_RTL8723BS;
339 #if defined(CONFIG_RTL8821A)
340 if (dvobj->chip_type == RTL8821) {
341 dvobj->HardwareType = HARDWARE_TYPE_RTL8821S;
342 DBG_871X("CHIP TYPE: RTL8821A\n");
346 #if defined(CONFIG_RTL8192E)
347 if (dvobj->chip_type == RTL8192E) {
348 dvobj->HardwareType = HARDWARE_TYPE_RTL8192ES;
349 DBG_871X("CHIP TYPE: RTL8192E\n");
353 #if defined(CONFIG_RTL8703B)
354 if (dvobj->chip_type == RTL8703B) {
355 dvobj->HardwareType = HARDWARE_TYPE_RTL8703BS;
356 DBG_871X("CHIP TYPE: RTL8703B\n");
360 #if defined(CONFIG_RTL8188F)
361 if (dvobj->chip_type == RTL8188F) {
362 dvobj->HardwareType = HARDWARE_TYPE_RTL8188FS;
363 DBG_871X("CHIP TYPE: RTL8188F\n");
368 static struct dvobj_priv *sdio_dvobj_init(struct sdio_func *func, const struct sdio_device_id *pdid)
371 struct dvobj_priv *dvobj = NULL;
375 if((dvobj = devobj_init()) == NULL) {
379 sdio_set_drvdata(func, dvobj);
381 psdio = &dvobj->intf_data;
384 if (sdio_init(dvobj) != _SUCCESS) {
385 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!\n", __FUNCTION__));
389 dvobj->interface_type = RTW_SDIO;
390 rtw_decide_chip_type_by_device_id(dvobj, pdid);
392 rtw_reset_continual_io_error(dvobj);
396 if (status != _SUCCESS && dvobj) {
397 sdio_set_drvdata(func, NULL);
399 devobj_deinit(dvobj);
408 static void sdio_dvobj_deinit(struct sdio_func *func)
410 struct dvobj_priv *dvobj = sdio_get_drvdata(func);
413 sdio_set_drvdata(func, NULL);
416 devobj_deinit(dvobj);
423 u8 rtw_set_hal_ops(PADAPTER padapter)
425 //alloc memory for HAL DATA
426 if(rtw_hal_data_init(padapter) == _FAIL)
429 #if defined(CONFIG_RTL8188E)
430 if (rtw_get_chip_type(padapter) == RTL8188E)
431 rtl8188es_set_hal_ops(padapter);
434 #if defined(CONFIG_RTL8723B)
435 if (rtw_get_chip_type(padapter) == RTL8723B)
436 rtl8723bs_set_hal_ops(padapter);
439 #if defined(CONFIG_RTL8821A)
440 if (rtw_get_chip_type(padapter) == RTL8821)
441 rtl8821as_set_hal_ops(padapter);
444 #if defined(CONFIG_RTL8192E)
445 if (rtw_get_chip_type(padapter) == RTL8192E)
446 rtl8192es_set_hal_ops(padapter);
449 #if defined(CONFIG_RTL8703B)
450 if (rtw_get_chip_type(padapter) == RTL8703B)
451 rtl8703bs_set_hal_ops(padapter);
454 #if defined(CONFIG_RTL8188F)
455 if (rtw_get_chip_type(padapter) == RTL8188F)
456 rtl8188fs_set_hal_ops(padapter);
459 if( rtw_hal_ops_check(padapter) == _FAIL)
462 if (hal_spec_init(padapter) == _FAIL)
468 static void sd_intf_start(PADAPTER padapter)
470 if (padapter == NULL) {
471 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__);
476 rtw_hal_enable_interrupt(padapter);
479 static void sd_intf_stop(PADAPTER padapter)
481 if (padapter == NULL) {
482 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__);
487 rtw_hal_disable_interrupt(padapter);
491 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
492 PADAPTER g_test_adapter = NULL;
493 #endif // RTW_SUPPORT_PLATFORM_SHUTDOWN
495 _adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj)
498 PADAPTER padapter = NULL;
500 padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter));
501 if (padapter == NULL)
504 if (loadparam(padapter) != _SUCCESS)
507 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
508 g_test_adapter = padapter;
509 #endif // RTW_SUPPORT_PLATFORM_SHUTDOWN
510 padapter->dvobj = dvobj;
512 rtw_set_drv_stopped(padapter);/*init*/
514 dvobj->padapters[dvobj->iface_nums++] = padapter;
515 padapter->iface_id = IFACE_ID0;
517 #if defined(CONFIG_CONCURRENT_MODE)
518 //set adapter_type/iface type for primary padapter
519 padapter->isprimary = _TRUE;
520 padapter->adapter_type = PRIMARY_ADAPTER;
521 #ifndef CONFIG_HWPORT_SWAP
522 padapter->iface_type = IFACE_PORT0;
524 padapter->iface_type = IFACE_PORT1;
528 //3 3. init driver special setting, interface, OS and hardware relative
530 //4 3.1 set hardware operation functions
531 if (rtw_set_hal_ops(padapter)== _FAIL)
534 //3 5. initialize Chip version
535 padapter->intf_start = &sd_intf_start;
536 padapter->intf_stop = &sd_intf_stop;
538 padapter->intf_init = &sdio_init;
539 padapter->intf_deinit = &sdio_deinit;
540 padapter->intf_alloc_irq = &sdio_alloc_irq;
541 padapter->intf_free_irq = &sdio_free_irq;
543 if (rtw_init_io_priv(padapter, sdio_set_intf_ops) == _FAIL)
545 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
546 ("rtw_drv_init: Can't init io_priv\n"));
550 rtw_hal_read_chip_version(padapter);
552 rtw_hal_chip_configure(padapter);
554 #ifdef CONFIG_BT_COEXIST
555 rtw_btcoex_Initialize(padapter);
556 #endif // CONFIG_BT_COEXIST
558 //3 6. read efuse/eeprom data
559 rtw_hal_read_chip_info(padapter);
561 //3 7. init driver common data
562 if (rtw_init_drv_sw(padapter) == _FAIL) {
563 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
564 ("rtw_drv_init: Initialize driver software resource Failed!\n"));
568 //3 8. get WLan MAC address
570 rtw_macaddr_cfg(adapter_mac_addr(padapter), get_hal_mac_addr(padapter));
572 rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter));
573 #endif /* CONFIG_P2P */
575 rtw_hal_disable_interrupt(padapter);
577 DBG_871X("bDriverStopped:%s, bSurpriseRemoved:%s, bup:%d, hw_init_completed:%d\n"
578 , rtw_is_drv_stopped(padapter)?"True":"False"
579 , rtw_is_surprise_removed(padapter)?"True":"False"
581 , rtw_get_hw_init_completed(padapter)
587 if (status != _SUCCESS && padapter->HalData)
588 rtw_hal_free_data(padapter);
591 if (status != _SUCCESS && padapter) {
592 rtw_vmfree((u8 *)padapter, sizeof(*padapter));
599 static void rtw_sdio_if1_deinit(_adapter *if1)
601 struct mlme_priv *pmlmepriv= &if1->mlmepriv;
603 if(check_fwstate(pmlmepriv, _FW_LINKED))
604 rtw_disassoc_cmd(if1, 0, _FALSE);
606 #ifdef CONFIG_AP_MODE
607 free_mlme_ap_info(if1);
608 #ifdef CONFIG_HOSTAPD_MLME
609 hostapd_mode_unload(if1);
613 #ifdef CONFIG_GPIO_WAKEUP
614 #ifdef CONFIG_PLATFORM_ARM_SUN6I
615 sw_gpio_eint_set_enable(gpio_eint_wlan, 0);
616 sw_gpio_irq_free(eint_wlan_handle);
618 gpio_hostwakeup_free_irq(if1);
624 adapter_to_pwrctl(if1)->wowlan_mode=_FALSE;
625 DBG_871X_LEVEL(_drv_always_, "%s wowlan_mode:%d\n", __func__, adapter_to_pwrctl(if1)->wowlan_mode);
626 #endif //CONFIG_WOWLAN
629 DBG_871X("+r871xu_dev_remove, hw_init_completed=%d\n", rtw_get_hw_init_completed(if1));
631 rtw_free_drv_sw(if1);
633 /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
634 rtw_os_ndev_free(if1);
636 rtw_vmfree((u8 *)if1, sizeof(_adapter));
638 #ifdef CONFIG_PLATFORM_RTD2880B
639 DBG_871X("wlan link down\n");
640 rtd2885_wlan_netlink_sendMsg("linkdown", "8712");
643 #ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
644 g_test_adapter = NULL;
645 #endif // RTW_SUPPORT_PLATFORM_SHUTDOWN
649 * drv_init() - a device potentially for us
651 * notes: drv_init() is called when the bus driver has located a card for us to support.
652 * We accept the new device by returning 0.
654 static int rtw_drv_init(
655 struct sdio_func *func,
656 const struct sdio_device_id *id)
659 struct net_device *pnetdev;
660 PADAPTER if1 = NULL, if2 = NULL;
661 struct dvobj_priv *dvobj;
663 #ifdef CONFIG_PLATFORM_INTEL_BYT
667 struct acpi_device *adev;
670 #if defined(CONFIG_ACPI) && defined(CONFIG_GPIO_WAKEUP)
671 handle = ACPI_HANDLE(&func->dev);
674 /* Dont try to do acpi pm for the wifi module */
675 if (!handle || acpi_bus_get_device(handle, &adev))
676 DBG_871X("Could not get acpi pointer!\n");
678 adev->flags.power_manageable = 0;
679 DBG_871X("Disabling ACPI power management support!\n");
681 oob_gpio = acpi_get_gpio_by_index(&func->dev, 0, NULL);
682 DBG_871X("rtw_drv_init: ACPI_HANDLE found oob_gpio %d!\n", oob_gpio);
683 wifi_configure_gpio();
686 DBG_871X("rtw_drv_init: ACPI_HANDLE NOT found!\n");
689 #if defined(CONFIG_ACPI)
690 if (&func->dev && ACPI_HANDLE(&func->dev)) {
691 wlan_en_gpio = acpi_get_gpio_by_index(&func->dev, 1, NULL);
692 DBG_871X("rtw_drv_init: ACPI_HANDLE found wlan_en %d!\n", wlan_en_gpio);
695 DBG_871X("rtw_drv_init: ACPI_HANDLE NOT found!\n");
697 #endif //CONFIG_PLATFORM_INTEL_BYT
700 RT_TRACE(_module_hci_intfs_c_, _drv_info_,
701 ("+rtw_drv_init: vendor=0x%04x device=0x%04x class=0x%02x\n",
702 func->vendor, func->device, func->class));
704 if ((dvobj = sdio_dvobj_init(func, id)) == NULL) {
705 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("initialize device object priv Failed!\n"));
709 if ((if1 = rtw_sdio_if1_init(dvobj)) == NULL) {
710 DBG_871X("rtw_init_primary_adapter Failed!\n");
714 #ifdef CONFIG_CONCURRENT_MODE
715 if ((if2 = rtw_drv_if2_init(if1, sdio_set_intf_ops)) == NULL) {
720 //dev_alloc_name && register_netdev
721 if (rtw_os_ndevs_init(dvobj) != _SUCCESS)
724 #ifdef CONFIG_HOSTAPD_MLME
725 hostapd_mode_init(if1);
728 #ifdef CONFIG_PLATFORM_RTD2880B
729 DBG_871X("wlan link up\n");
730 rtd2885_wlan_netlink_sendMsg("linkup", "8712");
733 if (sdio_alloc_irq(dvobj) != _SUCCESS)
734 goto os_ndevs_deinit;
736 #ifdef CONFIG_GPIO_WAKEUP
737 #ifdef CONFIG_PLATFORM_ARM_SUN6I
738 eint_wlan_handle = sw_gpio_irq_request(gpio_eint_wlan, TRIG_EDGE_NEGATIVE,(peint_handle)gpio_hostwakeup_irq_thread, NULL);
739 if (!eint_wlan_handle) {
740 DBG_871X( "%s: request irq failed\n",__func__);
744 gpio_hostwakeup_alloc_irq(if1);
748 #ifdef CONFIG_GLOBAL_UI_PID
750 DBG_871X("ui_pid[1]:%d\n",ui_pid[1]);
751 rtw_signal_process(ui_pid[1], SIGUSR2);
755 RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-871x_drv - drv_init, success!\n"));
760 if (status != _SUCCESS)
761 rtw_os_ndevs_deinit(dvobj);
763 if(status != _SUCCESS && if2) {
764 #ifdef CONFIG_CONCURRENT_MODE
765 rtw_drv_if2_stop(if2);
766 rtw_drv_if2_free(if2);
770 if (status != _SUCCESS && if1) {
771 rtw_sdio_if1_deinit(if1);
774 if (status != _SUCCESS)
775 sdio_dvobj_deinit(func);
777 return status == _SUCCESS?0:-ENODEV;
780 static void rtw_dev_remove(struct sdio_func *func)
782 struct dvobj_priv *dvobj = sdio_get_drvdata(func);
783 struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
784 PADAPTER padapter = dvobj->padapters[IFACE_ID0];
788 RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+rtw_dev_remove\n"));
790 dvobj->processing_dev_remove = _TRUE;
792 /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
793 rtw_os_ndevs_unregister(dvobj);
795 if (!rtw_is_surprise_removed(padapter)) {
798 /* test surprise remove */
799 sdio_claim_host(func);
800 sdio_readb(func, 0, &err);
801 sdio_release_host(func);
802 if (err == -ENOMEDIUM) {
803 rtw_set_surprise_removed(padapter);
804 DBG_871X(KERN_NOTICE "%s: device had been removed!\n", __func__);
808 #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
809 rtw_unregister_early_suspend(pwrctl);
812 if (padapter->bFWReady == _TRUE) {
813 rtw_ps_deny(padapter, PS_DENY_DRV_REMOVE);
814 rtw_pm_set_ips(padapter, IPS_NONE);
815 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
816 LeaveAllPowerSaveMode(padapter);
818 rtw_set_drv_stopped(padapter); /*for stop thread*/
820 /* stop cmd thread */
821 rtw_stop_cmd_thread(padapter);
822 #ifdef CONFIG_CONCURRENT_MODE
823 rtw_drv_if2_stop(dvobj->padapters[IFACE_ID1]);
826 #ifdef CONFIG_BT_COEXIST
827 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
828 if (GET_HAL_DATA(padapter)->EEPROMBluetoothCoexist)
829 rtw_btcoex_close_socket(padapter);
831 rtw_btcoex_HaltNotify(padapter);
834 rtw_sdio_if1_deinit(padapter);
836 #ifdef CONFIG_CONCURRENT_MODE
837 rtw_drv_if2_free(dvobj->padapters[IFACE_ID1]);
840 sdio_dvobj_deinit(func);
842 RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-rtw_dev_remove\n"));
846 extern int pm_netdev_open(struct net_device *pnetdev,u8 bnormal);
847 extern int pm_netdev_close(struct net_device *pnetdev,u8 bnormal);
849 static int rtw_sdio_suspend(struct device *dev)
851 struct sdio_func *func =dev_to_sdio_func(dev);
852 struct dvobj_priv *psdpriv = sdio_get_drvdata(func);
853 struct pwrctrl_priv *pwrpriv = NULL;
854 _adapter *padapter = NULL;
855 struct debug_priv *pdbgpriv = NULL;
862 pwrpriv = dvobj_to_pwrctl(psdpriv);
863 padapter = psdpriv->padapters[IFACE_ID0];
864 pdbgpriv = &psdpriv->drv_dbg;
865 if (rtw_is_drv_stopped(padapter)) {
866 DBG_871X("%s bDriverStopped == _TRUE\n", __func__);
870 if (pwrpriv->bInSuspend == _TRUE)
872 DBG_871X("%s bInSuspend = %d\n", __func__, pwrpriv->bInSuspend);
873 pdbgpriv->dbg_suspend_error_cnt++;
877 ret = rtw_suspend_common(padapter);
880 #ifdef CONFIG_RTW_SDIO_PM_KEEP_POWER
881 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
882 //Android 4.0 don't support WIFI close power
883 //or power down or clock will close after wifi resume,
884 //this is sprd's bug in Android 4.0, but sprd don't
886 //we have test power under 8723as, power consumption is ok
888 mmc_pm_flag_t pm_flag = 0;
889 pm_flag = sdio_get_host_pm_caps(func);
890 DBG_871X("cmd: %s: suspend: PM flag = 0x%x\n", sdio_func_id(func), pm_flag);
891 if (!(pm_flag & MMC_PM_KEEP_POWER)) {
892 DBG_871X("%s: cannot remain alive while host is suspended\n", sdio_func_id(func));
894 pdbgpriv->dbg_suspend_error_cnt++;
897 DBG_871X("cmd: suspend with MMC_PM_KEEP_POWER\n");
898 sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
905 int rtw_resume_process(_adapter *padapter)
907 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
908 struct dvobj_priv *psdpriv = padapter->dvobj;
909 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
911 if (pwrpriv->bInSuspend == _FALSE)
913 pdbgpriv->dbg_resume_error_cnt++;
914 DBG_871X("%s bInSuspend = %d\n", __FUNCTION__, pwrpriv->bInSuspend);
918 return rtw_resume_common(padapter);
921 static int rtw_sdio_resume(struct device *dev)
923 struct sdio_func *func =dev_to_sdio_func(dev);
924 struct dvobj_priv *psdpriv = sdio_get_drvdata(func);
925 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv);
926 _adapter *padapter = psdpriv->padapters[IFACE_ID0];
927 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
929 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
931 DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
933 pdbgpriv->dbg_resume_cnt++;
935 if(pwrpriv->bInternalAutoSuspend)
937 ret = rtw_resume_process(padapter);
941 #ifdef CONFIG_PLATFORM_INTEL_BYT
944 if(pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode)
947 rtw_resume_lock_suspend();
948 ret = rtw_resume_process(padapter);
949 rtw_resume_unlock_suspend();
953 #ifdef CONFIG_RESUME_IN_WORKQUEUE
954 rtw_resume_in_workqueue(pwrpriv);
956 if (rtw_is_earlysuspend_registered(pwrpriv))
958 /* jeff: bypass resume here, do in late_resume */
959 rtw_set_do_late_resume(pwrpriv, _TRUE);
963 rtw_resume_lock_suspend();
964 ret = rtw_resume_process(padapter);
965 rtw_resume_unlock_suspend();
970 pmlmeext->last_scan_time = rtw_get_current_time();
971 DBG_871X("<======== %s return %d\n", __FUNCTION__, ret);
976 static int rtw_drv_entry(void)
980 DBG_871X_LEVEL(_drv_always_, "module init start\n");
981 dump_drv_version(RTW_DBGDUMP);
983 DBG_871X_LEVEL(_drv_always_, DRV_NAME" BT-Coex version = %s\n", BTCOEXVERSION);
984 #endif // BTCOEXVERSION
986 ret = platform_wifi_power_on();
989 DBG_871X("%s: power on failed!!(%d)\n", __FUNCTION__, ret);
994 sdio_drvpriv.drv_registered = _TRUE;
995 rtw_suspend_lock_init();
997 rtw_ndev_notifier_register();
999 ret = sdio_register_driver(&sdio_drvpriv.r871xs_drv);
1002 sdio_drvpriv.drv_registered = _FALSE;
1003 rtw_suspend_lock_uninit();
1004 rtw_drv_proc_deinit();
1005 rtw_ndev_notifier_unregister();
1006 DBG_871X("%s: register driver failed!!(%d)\n", __FUNCTION__, ret);
1010 #ifndef CONFIG_PLATFORM_INTEL_BYT
1011 rtw_android_wifictrl_func_add();
1012 #endif //!CONFIG_PLATFORM_INTEL_BYT
1016 platform_wifi_power_off();
1019 DBG_871X_LEVEL(_drv_always_, "module init ret=%d\n", ret);
1023 static void rtw_drv_halt(void)
1025 DBG_871X_LEVEL(_drv_always_, "module exit start\n");
1027 sdio_drvpriv.drv_registered = _FALSE;
1029 sdio_unregister_driver(&sdio_drvpriv.r871xs_drv);
1031 rtw_android_wifictrl_func_del();
1033 platform_wifi_power_off();
1035 rtw_suspend_lock_uninit();
1036 rtw_drv_proc_deinit();
1037 rtw_ndev_notifier_unregister();
1039 DBG_871X_LEVEL(_drv_always_, "module exit success\n");
1041 rtw_mstat_dump(RTW_DBGDUMP);
1044 #ifdef CONFIG_PLATFORM_INTEL_BYT
1045 int rtw_sdio_set_power(int on)
1048 if(wlan_en_gpio >= 0){
1050 gpio_set_value(wlan_en_gpio,1);
1052 gpio_set_value(wlan_en_gpio,0);
1057 #endif //CONFIG_PLATFORM_INTEL_BYT
1059 #include <linux/rfkill-wlan.h>
1060 extern int get_wifi_chip_type(void);
1061 extern int rockchip_wifi_power(int on);
1062 extern int rockchip_wifi_set_carddetect(int val);
1064 int rockchip_wifi_init_module_rtkwifi(void)
1066 #ifdef CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
1067 int type = get_wifi_chip_type();
1068 if (type < WIFI_AP6XXX_SERIES || type == WIFI_ESP8089) return 0;
1071 printk("=======================================================\n");
1072 printk("==== Launching Wi-Fi driver! (Powered by Rockchip) ====\n");
1073 printk("=======================================================\n");
1074 printk("Realtek 8723BS SDIO WiFi driver (Powered by Rockchip,Ver %s) init.\n", DRIVERVERSION);
1076 rockchip_wifi_power(1);
1077 rockchip_wifi_set_carddetect(1);
1079 return rtw_drv_entry();
1082 void rockchip_wifi_exit_module_rtkwifi(void)
1084 #ifdef CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
1085 int type = get_wifi_chip_type();
1086 if (type < WIFI_AP6XXX_SERIES || type == WIFI_ESP8089) return;
1089 printk("=======================================================\n");
1090 printk("==== Dislaunching Wi-Fi driver! (Powered by Rockchip) ====\n");
1091 printk("=======================================================\n");
1092 printk("Realtek 8723BS SDIO WiFi driver (Powered by Rockchip,Ver %s) init.\n", DRIVERVERSION);
1096 rockchip_wifi_set_carddetect(0);
1097 rockchip_wifi_power(0);
1100 #ifdef CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
1101 late_initcall(rockchip_wifi_init_module_rtkwifi);
1102 module_exit(rockchip_wifi_exit_module_rtkwifi);
1104 EXPORT_SYMBOL(rockchip_wifi_init_module_rtkwifi);
1105 EXPORT_SYMBOL(rockchip_wifi_exit_module_rtkwifi);
1107 //module_init(rtw_drv_entry);
1108 //module_exit(rtw_drv_halt);