xref: /OK3568_Linux_fs/external/rkwifibt/drivers/bcmdhd/dhd_custom_msm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Platform Dependent file for Qualcomm MSM/APQ
3  *
4  * Copyright (C) 2020, Broadcom.
5  *
6  *      Unless you and Broadcom execute a separate written software license
7  * agreement governing use of this software, this software is licensed to you
8  * under the terms of the GNU General Public License version 2 (the "GPL"),
9  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10  * following added to such license:
11  *
12  *      As a special exception, the copyright holders of this software give you
13  * permission to link this software with independent modules, and to copy and
14  * distribute the resulting executable under terms of your choice, provided that
15  * you also meet, for each linked independent module, the terms and conditions of
16  * the license of that module.  An independent module is a module which is not
17  * derived from this software.  The special exception does not apply to any
18  * modifications of the software.
19  *
20  *
21  * <<Broadcom-WL-IPTag/Open:>>
22  *
23  * $Id$
24  *
25  */
26 
27 #include <linux/kernel.h>
28 #include <linux/init.h>
29 #include <linux/platform_device.h>
30 #include <linux/delay.h>
31 #include <linux/err.h>
32 #include <linux/gpio.h>
33 #include <linux/skbuff.h>
34 #include <linux/mmc/host.h>
35 #ifdef CONFIG_BCMDHD_PCIE
36 #include <linux/msm_pcie.h>
37 #endif /* CONFIG_BCMDHD_PCIE */
38 #include <linux/fcntl.h>
39 #include <linux/fs.h>
40 #include <linux/of_gpio.h>
41 #include <linux/wlan_plat.h>
42 
43 #ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
44 extern void dhd_exit_wlan_mem(void);
45 extern int dhd_init_wlan_mem(void);
46 extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
47 #endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
48 
49 #define WIFI_TURNON_DELAY       200
50 static int wlan_reg_on = -1;
51 #define DHD_DT_COMPAT_ENTRY		"android,bcmdhd_wlan"
52 #ifdef CUSTOMER_HW2
53 #define WIFI_WL_REG_ON_PROPNAME		"wl_reg_on"
54 #else
55 #define WIFI_WL_REG_ON_PROPNAME		"wlan-en-gpio"
56 #endif /* CUSTOMER_HW2 */
57 
58 #if defined(CONFIG_ARCH_MSM8996) || defined(CONFIG_ARCH_MSM8998) || \
59 	defined(CONFIG_ARCH_SDM845) || defined(CONFIG_ARCH_SM8150) || \
60 	defined(CONFIG_ARCH_KONA) || defined(CONFIG_ARCH_LAHAINA)
61 #define MSM_PCIE_CH_NUM			0
62 #else
63 #define MSM_PCIE_CH_NUM			1
64 #endif /* MSM PCIE Platforms */
65 
66 #ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
67 static int wlan_host_wake_up = -1;
68 static int wlan_host_wake_irq = 0;
69 #ifdef CUSTOMER_HW2
70 #define WIFI_WLAN_HOST_WAKE_PROPNAME    "wl_host_wake"
71 #else
72 #define WIFI_WLAN_HOST_WAKE_PROPNAME    "wlan-host-wake-gpio"
73 #endif /* CUSTOMER_HW2 */
74 #endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
75 
76 int __init
dhd_wifi_init_gpio(void)77 dhd_wifi_init_gpio(void)
78 {
79 	char *wlan_node = DHD_DT_COMPAT_ENTRY;
80 	struct device_node *root_node = NULL;
81 
82 	root_node = of_find_compatible_node(NULL, NULL, wlan_node);
83 	if (!root_node) {
84 		WARN(1, "failed to get device node of BRCM WLAN\n");
85 		return -ENODEV;
86 	}
87 
88 	/* ========== WLAN_PWR_EN ============ */
89 	wlan_reg_on = of_get_named_gpio(root_node, WIFI_WL_REG_ON_PROPNAME, 0);
90 	printk(KERN_INFO "%s: gpio_wlan_power : %d\n", __FUNCTION__, wlan_reg_on);
91 
92 	if (gpio_request_one(wlan_reg_on, GPIOF_OUT_INIT_LOW, "WL_REG_ON")) {
93 		printk(KERN_ERR "%s: Faiiled to request gpio %d for WL_REG_ON\n",
94 			__FUNCTION__, wlan_reg_on);
95 	} else {
96 		printk(KERN_ERR "%s: gpio_request WL_REG_ON done - WLAN_EN: GPIO %d\n",
97 			__FUNCTION__, wlan_reg_on);
98 	}
99 
100 	if (gpio_direction_output(wlan_reg_on, 1)) {
101 		printk(KERN_ERR "%s: WL_REG_ON failed to pull up\n", __FUNCTION__);
102 	} else {
103 		printk(KERN_ERR "%s: WL_REG_ON is pulled up\n", __FUNCTION__);
104 	}
105 
106 	if (gpio_get_value(wlan_reg_on)) {
107 		printk(KERN_INFO "%s: Initial WL_REG_ON: [%d]\n",
108 			__FUNCTION__, gpio_get_value(wlan_reg_on));
109 	}
110 
111 	/* Wait for WIFI_TURNON_DELAY due to power stability */
112 	msleep(WIFI_TURNON_DELAY);
113 
114 #ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
115 	/* ========== WLAN_HOST_WAKE ============ */
116 	wlan_host_wake_up = of_get_named_gpio(root_node, WIFI_WLAN_HOST_WAKE_PROPNAME, 0);
117 	printk(KERN_INFO "%s: gpio_wlan_host_wake : %d\n", __FUNCTION__, wlan_host_wake_up);
118 
119 #ifndef CUSTOMER_HW2
120 	if (gpio_request_one(wlan_host_wake_up, GPIOF_IN, "WLAN_HOST_WAKE")) {
121 		printk(KERN_ERR "%s: Faiiled to request gpio %d for WLAN_HOST_WAKE\n",
122 			__FUNCTION__, wlan_host_wake_up);
123 			return -ENODEV;
124 	} else {
125 		printk(KERN_ERR "%s: gpio_request WLAN_HOST_WAKE done"
126 			" - WLAN_HOST_WAKE: GPIO %d\n",
127 			__FUNCTION__, wlan_host_wake_up);
128 	}
129 #endif /* !CUSTOMER_HW2 */
130 
131 	gpio_direction_input(wlan_host_wake_up);
132 	wlan_host_wake_irq = gpio_to_irq(wlan_host_wake_up);
133 #endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
134 
135 #ifdef CONFIG_BCMDHD_PCIE
136 	printk(KERN_INFO "%s: Call msm_pcie_enumerate\n", __FUNCTION__);
137 	msm_pcie_enumerate(MSM_PCIE_CH_NUM);
138 #endif /* CONFIG_BCMDHD_PCIE */
139 
140 	return 0;
141 }
142 
143 int
dhd_wlan_power(int onoff)144 dhd_wlan_power(int onoff)
145 {
146 	printk(KERN_INFO"%s Enter: power %s\n", __func__, onoff ? "on" : "off");
147 
148 	if (onoff) {
149 		if (gpio_direction_output(wlan_reg_on, 1)) {
150 			printk(KERN_ERR "%s: WL_REG_ON is failed to pull up\n", __FUNCTION__);
151 			return -EIO;
152 		}
153 		if (gpio_get_value(wlan_reg_on)) {
154 			printk(KERN_INFO"WL_REG_ON on-step-2 : [%d]\n",
155 				gpio_get_value(wlan_reg_on));
156 		} else {
157 			printk("[%s] gpio value is 0. We need reinit.\n", __func__);
158 			if (gpio_direction_output(wlan_reg_on, 1)) {
159 				printk(KERN_ERR "%s: WL_REG_ON is "
160 					"failed to pull up\n", __func__);
161 			}
162 		}
163 	} else {
164 		if (gpio_direction_output(wlan_reg_on, 0)) {
165 			printk(KERN_ERR "%s: WL_REG_ON is failed to pull up\n", __FUNCTION__);
166 			return -EIO;
167 		}
168 		if (gpio_get_value(wlan_reg_on)) {
169 			printk(KERN_INFO"WL_REG_ON on-step-2 : [%d]\n",
170 				gpio_get_value(wlan_reg_on));
171 		}
172 	}
173 	return 0;
174 }
175 EXPORT_SYMBOL(dhd_wlan_power);
176 
177 static int
dhd_wlan_reset(int onoff)178 dhd_wlan_reset(int onoff)
179 {
180 	return 0;
181 }
182 
183 static int
dhd_wlan_set_carddetect(int val)184 dhd_wlan_set_carddetect(int val)
185 {
186 #ifdef CONFIG_BCMDHD_PCIE
187 	printk(KERN_INFO "%s: Call msm_pcie_enumerate\n", __FUNCTION__);
188 	msm_pcie_enumerate(MSM_PCIE_CH_NUM);
189 #endif /* CONFIG_BCMDHD_PCIE */
190 	return 0;
191 }
192 
193 #if defined(CONFIG_BCMDHD_OOB_HOST_WAKE) && defined(CONFIG_BCMDHD_GET_OOB_STATE)
194 int
dhd_get_wlan_oob_gpio(void)195 dhd_get_wlan_oob_gpio(void)
196 {
197 	return gpio_is_valid(wlan_host_wake_up) ?
198 		gpio_get_value(wlan_host_wake_up) : -1;
199 }
200 EXPORT_SYMBOL(dhd_get_wlan_oob_gpio);
201 #endif /* CONFIG_BCMDHD_OOB_HOST_WAKE && CONFIG_BCMDHD_GET_OOB_STATE */
202 
203 struct resource dhd_wlan_resources = {
204 	.name	= "bcmdhd_wlan_irq",
205 	.start	= 0, /* Dummy */
206 	.end	= 0, /* Dummy */
207 	.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE |
208 #ifdef CONFIG_BCMDHD_PCIE
209 	IORESOURCE_IRQ_HIGHEDGE,
210 #else
211 	IORESOURCE_IRQ_HIGHLEVEL,
212 #endif /* CONFIG_BCMDHD_PCIE */
213 };
214 EXPORT_SYMBOL(dhd_wlan_resources);
215 
216 struct wifi_platform_data dhd_wlan_control = {
217 	.set_power	= dhd_wlan_power,
218 	.set_reset	= dhd_wlan_reset,
219 	.set_carddetect	= dhd_wlan_set_carddetect,
220 #ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
221 	.mem_prealloc	= dhd_wlan_mem_prealloc,
222 #endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
223 };
224 EXPORT_SYMBOL(dhd_wlan_control);
225 
226 int __init
dhd_wlan_init(void)227 dhd_wlan_init(void)
228 {
229 	int ret;
230 
231 	printk(KERN_INFO"%s: START.......\n", __FUNCTION__);
232 	ret = dhd_wifi_init_gpio();
233 	if (ret < 0) {
234 		printk(KERN_ERR "%s: failed to initiate GPIO, ret=%d\n",
235 			__FUNCTION__, ret);
236 		goto fail;
237 	}
238 
239 #ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
240 	dhd_wlan_resources.start = wlan_host_wake_irq;
241 	dhd_wlan_resources.end = wlan_host_wake_irq;
242 #endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
243 
244 #ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
245 	ret = dhd_init_wlan_mem();
246 	if (ret < 0) {
247 		printk(KERN_ERR "%s: failed to alloc reserved memory,"
248 			" ret=%d\n", __FUNCTION__, ret);
249 	}
250 #endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
251 
252 fail:
253 	printk(KERN_INFO"%s: FINISH.......\n", __FUNCTION__);
254 	return ret;
255 }
256 
257 int
dhd_wlan_deinit(void)258 dhd_wlan_deinit(void)
259 {
260 #ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
261 	gpio_free(wlan_host_wake_up);
262 #endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
263 	gpio_free(wlan_reg_on);
264 
265 #ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
266 	dhd_exit_wlan_mem();
267 #endif /*  CONFIG_BROADCOM_WIFI_RESERVED_MEM */
268 	return 0;
269 }
270 
271 #ifndef BCMDHD_MODULAR
272 #if defined(CONFIG_ARCH_MSM8996) || defined(CONFIG_ARCH_MSM8998) || \
273 	defined(CONFIG_ARCH_SDM845) || defined(CONFIG_ARCH_SM8150) || \
274 	defined(CONFIG_ARCH_KONA) || defined(CONFIG_ARCH_LAHAINA)
275 #if defined(CONFIG_DEFERRED_INITCALLS)
276 deferred_module_init(dhd_wlan_init);
277 #else
278 late_initcall(dhd_wlan_init);
279 #endif /* CONFIG_DEFERRED_INITCALLS */
280 #else
281 device_initcall(dhd_wlan_init);
282 #endif /* MSM PCIE Platforms */
283 #endif /* !BCMDHD_MODULAR */
284