4 #include <linux/gpio.h>
6 #if defined(BUS_POWER_RESTORE) && defined(BCMSDIO)
7 #include <linux/mmc/core.h>
8 #include <linux/mmc/card.h>
9 #include <linux/mmc/host.h>
10 #include <linux/mmc/sdio_func.h>
11 #endif /* defined(BUS_POWER_RESTORE) && defined(BCMSDIO) */
13 #ifdef CONFIG_DHD_USE_STATIC_BUF
14 extern void *bcmdhd_mem_prealloc(int section
, unsigned long size
);
15 #endif /* CONFIG_DHD_USE_STATIC_BUF */
17 static int gpio_wl_reg_on
= -1; // WL_REG_ON is input pin of WLAN module
19 static int gpio_wl_host_wake
= -1; // WL_HOST_WAKE is output pin of WLAN module
22 #ifdef CUSTOMER_HW_AMLOGIC
23 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
24 #include <linux/amlogic/aml_gpio_consumer.h>
25 extern int wifi_irq_trigger_level(void);
26 extern u8
*wifi_get_mac(void);
27 extern u8
*wifi_get_ap_mac(void);
29 extern void sdio_reinit(void);
30 extern void set_usb_bt_power(int is_power
);
31 extern void extern_wifi_set_enable(int is_on
);
32 extern void pci_remove_reinit(unsigned int vid
, unsigned int pid
, int delBus
);
33 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
34 extern int wifi_irq_num(void);
39 dhd_wlan_set_power(int on
40 #ifdef BUS_POWER_RESTORE
41 , wifi_adapter_info_t
*adapter
42 #endif /* BUS_POWER_RESTORE */
48 printf("======== PULL WL_REG_ON(%d) HIGH! ========\n", gpio_wl_reg_on
);
49 if (gpio_wl_reg_on
>= 0) {
50 err
= gpio_direction_output(gpio_wl_reg_on
, 1);
52 printf("%s: WL_REG_ON didn't output high\n", __FUNCTION__
);
56 #ifdef CUSTOMER_HW_AMLOGIC
58 extern_wifi_set_enable(0);
60 extern_wifi_set_enable(1);
71 #if defined(BUS_POWER_RESTORE)
72 #if defined(BCMSDIO) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0))
73 if (adapter
->sdio_func
&& adapter
->sdio_func
->card
&& adapter
->sdio_func
->card
->host
) {
75 printf("======== mmc_power_restore_host! ========\n");
76 mmc_power_restore_host(adapter
->sdio_func
->card
->host
);
78 #elif defined(BCMPCIE)
79 if (adapter
->pci_dev
) {
81 printf("======== pci_set_power_state PCI_D0! ========\n");
82 pci_set_power_state(adapter
->pci_dev
, PCI_D0
);
83 if (adapter
->pci_saved_state
)
84 pci_load_and_free_saved_state(adapter
->pci_dev
, &adapter
->pci_saved_state
);
85 pci_restore_state(adapter
->pci_dev
);
86 err
= pci_enable_device(adapter
->pci_dev
);
88 printf("%s: PCI enable device failed", __FUNCTION__
);
89 pci_set_master(adapter
->pci_dev
);
92 #endif /* BUS_POWER_RESTORE */
93 /* Lets customer power to get stable */
96 #if defined(BUS_POWER_RESTORE)
97 #if defined(BCMSDIO) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0))
98 if (adapter
->sdio_func
&& adapter
->sdio_func
->card
&& adapter
->sdio_func
->card
->host
) {
99 printf("======== mmc_power_save_host! ========\n");
100 mmc_power_save_host(adapter
->sdio_func
->card
->host
);
102 #elif defined(BCMPCIE)
103 if (adapter
->pci_dev
) {
104 printf("======== pci_set_power_state PCI_D3hot! ========\n");
105 pci_save_state(adapter
->pci_dev
);
106 adapter
->pci_saved_state
= pci_store_saved_state(adapter
->pci_dev
);
107 if (pci_is_enabled(adapter
->pci_dev
))
108 pci_disable_device(adapter
->pci_dev
);
109 pci_set_power_state(adapter
->pci_dev
, PCI_D3hot
);
112 #endif /* BUS_POWER_RESTORE */
113 printf("======== PULL WL_REG_ON(%d) LOW! ========\n", gpio_wl_reg_on
);
114 if (gpio_wl_reg_on
>= 0) {
115 err
= gpio_direction_output(gpio_wl_reg_on
, 0);
117 printf("%s: WL_REG_ON didn't output low\n", __FUNCTION__
);
121 #ifdef CUSTOMER_HW_AMLOGIC
123 extern_wifi_set_enable(0);
136 static int dhd_wlan_set_reset(int onoff
)
141 static int dhd_wlan_set_carddetect(int present
)
145 #if !defined(BUS_POWER_RESTORE)
148 printf("======== Card detection to detect SDIO card! ========\n");
149 #ifdef CUSTOMER_HW_PLATFORM
150 err
= sdhci_force_presence_change(&sdmmc_channel
, 1);
151 #endif /* CUSTOMER_HW_PLATFORM */
152 #ifdef CUSTOMER_HW_AMLOGIC
155 #elif defined(BCMPCIE)
156 printf("======== Card detection to detect PCIE card! ========\n");
160 printf("======== Card detection to remove SDIO card! ========\n");
161 #ifdef CUSTOMER_HW_PLATFORM
162 err
= sdhci_force_presence_change(&sdmmc_channel
, 0);
163 #endif /* CUSTOMER_HW_PLATFORM */
164 #ifdef CUSTOMER_HW_AMLOGIC
165 extern_wifi_set_enable(0);
168 #elif defined(BCMPCIE)
169 printf("======== Card detection to remove PCIE card! ========\n");
170 #ifdef CUSTOMER_HW_AMLOGIC
171 extern_wifi_set_enable(0);
176 #endif /* BUS_POWER_RESTORE */
181 static int dhd_wlan_get_mac_addr(unsigned char *buf
182 #ifdef CUSTOM_MULTI_MAC
189 #ifdef CUSTOM_MULTI_MAC
190 if (!strcmp("wlan1", name
)) {
191 #ifdef CUSTOMER_HW_AMLOGIC
193 bcopy((char *)wifi_get_ap_mac(), buf
, sizeof(struct ether_addr
));
194 if (buf
[0] == 0xff) {
195 printf("custom wifi ap mac is not set\n");
198 printf("custom wifi ap mac-addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
199 buf
[0], buf
[1], buf
[2],
200 buf
[3], buf
[4], buf
[5]);
206 #endif /* CUSTOM_MULTI_MAC */
208 #ifdef CUSTOMER_HW_AMLOGIC
209 bcopy((char *)wifi_get_mac(), buf
, sizeof(struct ether_addr
));
210 if (buf
[0] == 0xff) {
211 printf("custom wifi mac is not set\n");
214 printf("custom wifi mac-addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
215 buf
[0], buf
[1], buf
[2],
216 buf
[3], buf
[4], buf
[5]);
220 #ifdef EXAMPLE_GET_MAC_VER2
224 0x00,0xaa,0x9c,0x84,0xc7,0xbc,0x9b,0xf6,
225 0x02,0x33,0xa9,0x4d,0x5c,0xb4,0x0a,0x5d,
226 0xa8,0xef,0xb0,0xcf,0x8e,0xbf,0x24,0x8a,
227 0x87,0x0f,0x6f,0x0d,0xeb,0x83,0x6a,0x70,
228 0x4a,0xeb,0xf6,0xe6,0x3c,0xe7,0x5f,0xfc,
229 0x0e,0xa7,0xb3,0x0f,0x00,0xe4,0x4a,0xaf,
230 0x87,0x08,0x16,0x6d,0x3a,0xe3,0xc7,0x80};
231 bcopy(macpad
, buf
+6, sizeof(macpad
));
233 #endif /* EXAMPLE_GET_MAC_VER2 */
235 printf("======== %s err=%d ========\n", __FUNCTION__
, err
);
240 static struct cntry_locales_custom brcm_wlan_translate_custom_table
[] = {
241 /* Table should be filled out based on custom platform regulatory requirement */
243 {"", "XT", 49}, /* Universal if Country code is unknown or empty */
245 #endif /* EXMAPLE_TABLE */
248 #ifdef CUSTOM_FORCE_NODFS_FLAG
249 struct cntry_locales_custom brcm_wlan_translate_nodfs_table
[] = {
251 {"", "XT", 50}, /* Universal if Country code is unknown or empty */
253 #endif /* EXMAPLE_TABLE */
257 static void *dhd_wlan_get_country_code(char *ccode
258 #ifdef CUSTOM_FORCE_NODFS_FLAG
263 struct cntry_locales_custom
*locales
;
270 #ifdef CUSTOM_FORCE_NODFS_FLAG
271 if (flags
& WLAN_PLAT_NODFS_FLAG
) {
272 locales
= brcm_wlan_translate_nodfs_table
;
273 size
= ARRAY_SIZE(brcm_wlan_translate_nodfs_table
);
276 locales
= brcm_wlan_translate_custom_table
;
277 size
= ARRAY_SIZE(brcm_wlan_translate_custom_table
);
278 #ifdef CUSTOM_FORCE_NODFS_FLAG
282 for (i
= 0; i
< size
; i
++)
283 if (strcmp(ccode
, locales
[i
].iso_abbrev
) == 0)
288 struct resource dhd_wlan_resources
[] = {
290 .name
= "bcmdhd_wlan_irq",
291 .start
= 0, /* Dummy */
292 .end
= 0, /* Dummy */
293 .flags
= IORESOURCE_IRQ
| IORESOURCE_IRQ_SHAREABLE
294 | IORESOURCE_IRQ_HIGHLEVEL
, /* Dummy */
298 struct wifi_platform_data dhd_wlan_control
= {
299 .set_power
= dhd_wlan_set_power
,
300 .set_reset
= dhd_wlan_set_reset
,
301 .set_carddetect
= dhd_wlan_set_carddetect
,
302 .get_mac_addr
= dhd_wlan_get_mac_addr
,
303 #ifdef CONFIG_DHD_USE_STATIC_BUF
304 .mem_prealloc
= bcmdhd_mem_prealloc
,
305 #endif /* CONFIG_DHD_USE_STATIC_BUF */
306 .get_country_code
= dhd_wlan_get_country_code
,
309 int dhd_wlan_init_gpio(void)
313 int host_oob_irq
= -1;
314 uint host_oob_irq_flags
= 0;
317 /* Please check your schematic and fill right GPIO number which connected to
318 * WL_REG_ON and WL_HOST_WAKE.
322 gpio_wl_host_wake
= -1;
325 #ifdef CUSTOMER_HW_AMLOGIC
327 printf("======== Card detection to detect PCIE card! ========\n");
328 //pci_remove_reinit(0x14e4, 0x449d, 1);
332 if (gpio_wl_reg_on
>= 0) {
333 err
= gpio_request(gpio_wl_reg_on
, "WL_REG_ON");
335 printf("%s: gpio_request(%d) for WL_REG_ON failed\n",
336 __FUNCTION__
, gpio_wl_reg_on
);
342 if (gpio_wl_host_wake
>= 0) {
343 err
= gpio_request(gpio_wl_host_wake
, "bcmdhd");
345 printf("%s: gpio_request(%d) for WL_HOST_WAKE failed\n",
346 __FUNCTION__
, gpio_wl_host_wake
);
349 err
= gpio_direction_input(gpio_wl_host_wake
);
351 printf("%s: gpio_direction_input(%d) for WL_HOST_WAKE failed\n",
352 __FUNCTION__
, gpio_wl_host_wake
);
353 gpio_free(gpio_wl_host_wake
);
356 host_oob_irq
= gpio_to_irq(gpio_wl_host_wake
);
357 if (host_oob_irq
< 0) {
358 printf("%s: gpio_to_irq(%d) for WL_HOST_WAKE failed\n",
359 __FUNCTION__
, gpio_wl_host_wake
);
360 gpio_free(gpio_wl_host_wake
);
364 #ifdef CUSTOMER_HW_AMLOGIC
365 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
366 host_oob_irq
= INT_GPIO_4
;
368 host_oob_irq
= wifi_irq_num();
373 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
374 if (wifi_irq_trigger_level() == GPIO_IRQ_LOW
)
375 host_oob_irq_flags
= IORESOURCE_IRQ
| IORESOURCE_IRQ_LOWLEVEL
| IORESOURCE_IRQ_SHAREABLE
;
377 host_oob_irq_flags
= IORESOURCE_IRQ
| IORESOURCE_IRQ_HIGHLEVEL
| IORESOURCE_IRQ_SHAREABLE
;
379 #ifdef HW_OOB_LOW_LEVEL
380 host_oob_irq_flags
= IORESOURCE_IRQ
| IORESOURCE_IRQ_LOWLEVEL
| IORESOURCE_IRQ_SHAREABLE
;
382 host_oob_irq_flags
= IORESOURCE_IRQ
| IORESOURCE_IRQ_HIGHLEVEL
| IORESOURCE_IRQ_SHAREABLE
;
386 host_oob_irq_flags
= IORESOURCE_IRQ
| IORESOURCE_IRQ_HIGHEDGE
| IORESOURCE_IRQ_SHAREABLE
;
389 dhd_wlan_resources
[0].start
= dhd_wlan_resources
[0].end
= host_oob_irq
;
390 dhd_wlan_resources
[0].flags
= host_oob_irq_flags
;
391 printf("%s: WL_HOST_WAKE=%d, oob_irq=%d, oob_irq_flags=0x%x\n", __FUNCTION__
,
392 gpio_wl_host_wake
, host_oob_irq
, host_oob_irq_flags
);
393 #endif /* CUSTOMER_OOB */
394 printf("%s: WL_REG_ON=%d\n", __FUNCTION__
, gpio_wl_reg_on
);
399 static void dhd_wlan_deinit_gpio(void)
401 if (gpio_wl_reg_on
>= 0) {
402 printf("%s: gpio_free(WL_REG_ON %d)\n", __FUNCTION__
, gpio_wl_reg_on
);
403 gpio_free(gpio_wl_reg_on
);
407 if (gpio_wl_host_wake
>= 0) {
408 printf("%s: gpio_free(WL_HOST_WAKE %d)\n", __FUNCTION__
, gpio_wl_host_wake
);
409 gpio_free(gpio_wl_host_wake
);
410 gpio_wl_host_wake
= -1;
412 #endif /* CUSTOMER_OOB */
415 int dhd_wlan_init_plat_data(void)
419 printf("======== %s ========\n", __FUNCTION__
);
420 err
= dhd_wlan_init_gpio();
424 void dhd_wlan_deinit_plat_data(wifi_adapter_info_t
*adapter
)
426 printf("======== %s ========\n", __FUNCTION__
);
427 dhd_wlan_deinit_gpio();