平台环境:IMX6-sabresd_6dq Android4.4.2 Linux3.0.35
WiFi模块:AP6181 (BCM43362)
Linux3.0.35已经是支持博通的芯片,可以看到 kernel_imx/drivers/net/wireless 下面有几款博通芯片(bcm4329/bcm4330/bcmdhd)的驱动源码,AP6181WiFi模块用的bcm43362这款,所以这里选择bcmdhd。驱动有了,就开始配置:
[*] Networking support --->
-*- Wireless --->
Device Drivers --->
[*] Network device support --->
[*] Wireless LAN --->
配置保存退出,不论行不行 ,先试试,make 后再编译模块 make modules ,在bcmdhd目录下会产生bcmdhd,ko文件,将.ko文件放到SD内通过命令挂载发现并没有成功,仔细阅读源码,发现自带的bcmdhd版本太低,连WiFi的几个控制引脚也没有实现,到朋友那边拿了一份新版的bcmdhd的源码替代后;
修改bcmdhd配置
drivers/net/wireless/bcmdhd/Makefile
.....
ifeq ($(CONFIG_MACH_MX6Q_SABRESD),y)
DHDOFILES += dhd_gpio.o
DHDCFLAGS += -Iarch/arm/plat-mxc/include
DHDCFLAGS += -DCUSTOMER_HW
#DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI
endif
.....
根据原理图修改WiFi的控制引脚 drivers/net/wireless/bcmdhd/dhd_gpio.c
#include
#ifdef CUSTOMER_HW
#ifdef CONFIG_MACH_MX6Q_SABRESD
#include
#define BOARD_GPIO_WIFI_EN IMX_GPIO_NR(6, 15)
#define BOARD_GPIO_WIFI_HOST_WAKE IMX_GPIO_NR(1, 1)
#define BOARD_GPIO_WIFI_PDN IMX_GPIO_NR(1, 2)
#endif
#ifdef CUSTOMER_OOB
int bcm_wlan_get_oob_irq(void)
{
int host_oob_irq = 0;
#ifdef CONFIG_MACH_MX6Q_SABRESD
printk("GPIO(WL_HOST_WAKE) = IMX_GPIO_NR(1, 1) = %d\n", IMX_GPIO_NR(1, 1));
host_oob_irq = gpio_to_irq(BOARD_GPIO_WIFI_HOST_WAKE);
gpio_direction_input(BOARD_GPIO_WIFI_HOST_WAKE);
printk("host_oob_irq: %d \r\n", host_oob_irq);
#endif
return host_oob_irq;
}
#endif
void bcm_wlan_power_on(int flag)
{
if (flag == 1) {
printk("======== PULL WL_REG_ON HIGH! ========\n");
#ifdef CONFIG_MACH_MX6Q_SABRESD
/* Lets customer power to get stable */
mdelay(100);
gpio_set_value(BOARD_GPIO_WIFI_PDN, 1);
#endif
} else {
printk("======== PULL WL_REG_ON HIGH! (flag = %d) ========\n", flag);
#ifdef CONFIG_MACH_MX6Q_SABRESD
gpio_set_value(BOARD_GPIO_WIFI_PDN, 1);
#endif
}
}
void bcm_wlan_power_off(int flag)
{
if (flag == 1) {
#ifdef CONFIG_MACH_MX6Q_SABRESD
mdelay(100);
printk("======== PULL WL_REG_ON LOW! ========\n");
gpio_set_value(BOARD_GPIO_WIFI_PDN, 0);
#endif
} else {
printk("======== PULL WL_REG_ON LOW! (flag = %d) ========\n", flag);
#ifdef CONFIG_MACH_MX6Q_SABRESD
gpio_set_value(BOARD_GPIO_WIFI_PDN, 0);
#endif
}
}
#endif /* CUSTOMER_HW */
/* USDHC2 */
MX6DL_PAD_SD2_CLK__USDHC2_CLK,
MX6DL_PAD_SD2_CMD__USDHC2_CMD,
MX6DL_PAD_SD2_DAT0__USDHC2_DAT0,
MX6DL_PAD_SD2_DAT1__USDHC2_DAT1,
MX6DL_PAD_SD2_DAT2__USDHC2_DAT2,
MX6DL_PAD_SD2_DAT3__USDHC2_DAT3,
/* WIFI3V3_EN */
MX6DL_PAD_NANDF_CS2__GPIO_6_15,
/* WIFI_HOST_WAKE */
MX6DL_PAD_GPIO_1__GPIO_1_1,
/* WIFI_PDN */
MX6DL_PAD_GPIO_2__GPIO_1_2,
......
#define BOARD_GPIO_WIFI_EN IMX_GPIO_NR(6, 15)
#define BOARD_GPIO_WIFI_HOST_WAKE IMX_GPIO_NR(1, 1)
#define BOARD_GPIO_WIFI_PDN IMX_GPIO_NR(1, 2)
static const struct esdhc_platform_data mx6q_sabresd_sd2_data __initconst = {
.always_present = 1,
.keep_power_at_suspend = 1,
.delay_line = 0,
.cd_type = ESDHC_CD_PERMANENT
};
......
static void mx6_gpio_init(void)
{
......
//WIFI_3v3 en
gpio_request(BOARD_GPIO_WIFI_EN, "wifi-en");
gpio_direction_output(BOARD_GPIO_WIFI_EN, 1);
//BOARD_GPIO_WIFI_PDN
gpio_request(BOARD_GPIO_WIFI_PDN, "wifi-pdn");
gpio_direction_output(BOARD_GPIO_WIFI_PDN, 1);
......
}
static void __init mx6_sabresd_board_init(void)
{
......
imx6q_add_sdhci_usdhc_imx(1, &mx6q_sabresd_sd2_data);
......
}
[ 59.978823] dhd_module_init: Enter
[ 59.982815] ======== PULL WL_REG_ON HIGH! ========
[ 61.091332] ======== Card detection to detect SDIO card! ========
[ 61.097649] =========== WLAN placed in POWER ON ========
[ 61.102964] chiup_sem=0
[ 61.105806] bcmsdh_register: Linux Kernel SDIO/MMC Driver
[ 61.111394] GPIO(WL_HOST_WAKE) = IMX_GPIO_NR(1, 1) = 1
[ 61.116564] ------------[ cut here ]------------
[ 61.121203] WARNING: at drivers/gpio/gpiolib.c:101 gpio_ensure_requested+0x54/0x1b0()
[ 61.129036] autorequest GPIO-1
[ 61.132091] Modules linked in: bcmdhd(+)
[ 61.136065] [] (unwind_backtrace+0x0/0x138) from [] (warn_slowpath_common+0x4c/0x64)
[ 61.145558] [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_fmt+0x30/0x40)
[ 61.155138] [] (warn_slowpath_fmt+0x30/0x40) from [] (gpio_ensure_requested+0x54/0x1b0)
[ 61.164893] [] (gpio_ensure_requested+0x54/0x1b0) from [] (gpio_direction_input+0xa4/0x1fc)
[ 61.175181] [] (gpio_direction_input+0xa4/0x1fc) from [] (bcm_wlan_get_oob_irq+0x1c/0x34 [bcmdhd])
[ 61.186164] [] (bcm_wlan_get_oob_irq+0x1c/0x34 [bcmdhd]) from [] (bcmsdh_probe+0x28/0x1b0 [bcmdhd])
[ 61.197179] [] (bcmsdh_probe+0x28/0x1b0 [bcmdhd]) from [] (bcmsdh_sdmmc_probe+0x78/0x1b8 [bcmdhd])
[ 61.207987] [] (bcmsdh_sdmmc_probe+0x78/0x1b8 [bcmdhd]) from [] (sdio_bus_probe+0xd4/0x100)
[ 61.218097] [] (sdio_bus_probe+0xd4/0x100) from [] (driver_probe_device+0xb0/0x290)
[ 61.227506] [] (driver_probe_device+0xb0/0x290) from [] (__driver_attach+0x8c/0x90)
[ 61.236912] [] (__driver_attach+0x8c/0x90) from [] (bus_for_each_dev+0x5c/0x88)
[ 61.245970] [] (bus_for_each_dev+0x5c/0x88) from [] (bus_add_driver+0x188/0x268)
[ 61.255113] [] (bus_add_driver+0x188/0x268) from [] (driver_register+0x78/0x13c)
[ 61.264358] [] (driver_register+0x78/0x13c) from [] (sdio_function_init+0x44/0x8c [bcmdhd])
[ 61.274663] [] (sdio_function_init+0x44/0x8c [bcmdhd]) from [] (dhd_module_init+0x110/0x2ac [bcmdhd])
[ 61.285740] [] (dhd_module_init+0x110/0x2ac [bcmdhd]) from [] (do_one_initcall+0xfc/0x164)
[ 61.295758] [] (do_one_initcall+0xfc/0x164) from [] (sys_init_module+0xdc8/0x1c78)
[ 61.305082] [] (sys_init_module+0xdc8/0x1c78) from [] (ret_fast_syscall+0x0/0x30)
[ 61.314308] ---[ end trace e281d41a6c628d66 ]---
[ 61.319035] host_oob_irq: 257
[ 61.322573] dhdsdio_probe : no mutex held. set lock
[ 61.327497] FW_PATH:/system/etc/firmware/fw_bcm40181a2.bin
[ 61.332999] NV_PATH:/system/etc/firmware/nvram.txt
[ 61.337824] CF_PATH:/system/etc/firmware/config.txt
[ 61.343061] dhd_conf_set_hw_oob_intr: Enable HW OOB for 43362
[ 61.352411] F1 signature OK, socitype:0x1 chip:0xa962 rev:0x1 pkg:0x9
[ 61.359949] DHD: dongle ram size is set to 245760(orig 245760) at 0x0
[ 61.367292] dhdsdio_probe: Disable prop_txstatus
[ 61.373196] wl_create_event_handler(): thread:wl_event_handler:b36 started
[ 61.380108] tsk Enter, tsk = 0xd1be1398
[ 61.386828] p2p0: P2P Interface Registered
D/Tethering( 2382): sendTetherSta[ 61.393713] dhd_attach(): thread:dhd_watchdog_thread:b3d started
teChangedBroadcast 0, 0, 0
D/Tet[ 61.402373] dhd_attach(): thread:dhd_dpc:b3f started
hering( 2382): InitialState.proce[ 61.410053] dhd_attach(): thread:dhd_sysioc:b40 started
ssMessage what=4
D/Tethering( 2382): sendTetherStateChangedBroad[ 61.421359] Broadcom Dongle Host Driver: register interface [wlan0] MAC: 00:90:4c:11:22:33
cast 0, 0, 0
W/SocketClient( 204[ 61.433299] dhdsdio_probe : the lock is released.
2): write error (Broken pipe)
D/Tethering( 2382): sendTetherSt[ 61.444224]
[ 61.444230] Dongle Host Driver, version 1.88.45.3 (r420671)
[ 61.444235] Compiled in drivers/net/wireless/bcmdhd on Aug 23 2015 at 12:34:30
ateChangedBroadcast 0, 0, 0
D/Te[ 61.460405] ======== PULL WL_REG_ON LOW! (flag = 2) ========
thering( 2382): InitialState.proc[ 61.468651] =========== WLAN placed in RESET ========
essMessage what=4
D/Tethering( 2[ 61.476456] dhd_module_init: Exit error=0
提示初始化错误为0 ,说明WiFi模块驱动已经成功了!
通过wireless-tools测试驱动可以正常工作 ,具体操作流程参照上章节