RK3288 Android 6.0 适配 RTL8821CU wifi&BT 功能
需求背景
项目需求,要求添加蓝牙功能,选择的芯片是WIFI&蓝牙二合一的 RTL8821CU
.
为此,需要更新蓝牙和wifi的相关驱动,以及Android系统层的一些配置,同时还要向下兼容旧的wifi芯片 RTL8188EU.
相关文件
# kernel
## config
kernel/arch/arm/configs/rockchip_defconfig
## dts
kernel/arch/arm/boot/dts/rk3288-tb_8846.dts
## wifi
kernel/drivers/net/wireless/rockchip_wlan/rtl8821cu/*
kernel/drivers/net/wireless/rockchip_wlan/rtl8821cu/Makefile
kernel/drivers/net/wireless/rockchip_wlan/wifi_sys/rkwifi_sys_iface.c
kernel/drivers/net/wireless/Kconfig
kernel/drivers/net/wireless/Makefile
kernel/include/linux/rfkill-wlan.h
kernel/net/rfkill/rfkill-wlan.c
## bt
kernel/drivers/bluetooth/rtk_btusb.c
kernel/drivers/bluetooth/rtk_btusb.h
# vendor
## wifi
vendor/rockchip/common/wifi/modules/8188eu.ko
vendor/rockchip/common/wifi/modules/8821cu.ko
## bt
vendor/rockchip/common/bluetooth/bluetooth.mk
vendor/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/device-rtl.mk
vendor/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_config
vendor/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_fw
## hci tools
vendor/rockchip/common/rftesttool/broadcom/broadcom.mk
vendor/rockchip/common/rftesttool/rftesttool.mk
# device/rockchip/rk3288
device/rockchip/rk3288/init.rc
kernel
config
在内核配置中启用RTL8821CU.
--- a/arch/arm/configs/rockchip_defconfig
+++ b/arch/arm/configs/rockchip_defconfig
@@ -298,8 +298,9 @@ CONFIG_USB_HSO=y
CONFIG_USB_NET_INT51X1=y
CONFIG_USB_IPHETH=y
CONFIG_USB_SIERRA_NET=y
-CONFIG_RTL8188EU=y
CONFIG_ESP8089=y
+CONFIG_RTL8188EU=m
+CONFIG_RTL8821CU=m
CONFIG_RKWIFI=y
CONFIG_AP6335=y
# CONFIG_INPUT_MOUSEDEV is not set
dts
在 dts 将wifi_chip_type 改成 RTL8723BU, 注意!是RTL8723BU, 而不是RTL8821CU.
这一步非常关键,RK3288 android 6.0 sdk默认支持RTL8723BU, 但是还不支持RTL8821CU.也就是说明,安卓系统层只支持RTL8723BU, 而不支持RTL8821CU. 如果不修改,那么蓝牙打开时不会触发驱动层去打开蓝牙。
--- a/arch/arm/boot/dts/rk3288-tb_8846.dts
+++ b/arch/arm/boot/dts/rk3288-tb_8846.dts
@@ -15,8 +15,8 @@
* rtl8188eu, rtl8723bs, rtl8723bu
* esp8089
*/
-//wifi_chip_type = "rtl8723bu";
-wifi_chip_type = "rtl8188eu";
+wifi_chip_type = "rtl8723bu";
+//wifi_chip_type = "rtl8188eu";
sdio_vref = <1800>; //1800mv or 3300mv
wifi
wifi 驱动移植相对简单,把RTL8821CU的wifi驱动拷贝到 kernel/drivers/net/wireless/rockchip_wlan/rtl8821cu
目录,然后添加和修改相应的Kconfig, Makefile等即可。
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 4e3af3d..5213afe 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -45,6 +45,7 @@ choice
bool "No Realtek WiFi"
source "drivers/net/wireless/rockchip_wlan/rtl8188eu/Kconfig"
+source "drivers/net/wireless/rockchip_wlan/rtl8821cu/Kconfig"
source "drivers/net/wireless/rockchip_wlan/rtl8189es/Kconfig"
source "drivers/net/wireless/rockchip_wlan/rtl8192cu/Kconfig"
source "drivers/net/wireless/rockchip_wlan/rtl8192du/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index c3c8b85..4f18726 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -5,6 +5,7 @@ obj-y += rockchip_wlan/wifi_sys/rkwifi_sys_iface.o
obj-$(CONFIG_RTL8192CU) += rockchip_wlan/rtl8192cu/
obj-$(CONFIG_RTL8192DU) += rockchip_wlan/rtl8192du/
obj-$(CONFIG_RTL8188EU) += rockchip_wlan/rtl8188eu/
+obj-$(CONFIG_RTL8821CU) += rockchip_wlan/rtl8821cu/
obj-$(CONFIG_RTL8189ES) += rockchip_wlan/rtl8189es/
obj-$(CONFIG_RTL8723AU) += rockchip_wlan/rtl8723au/
obj-$(CONFIG_RTL8723BU) += rockchip_wlan/rtl8723bu/
diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cu/Makefile b/drivers/net/wireless/rockchip_wlan/rtl8821cu/Makefile
index 850fb5a..3a6bacc 100644
--- a/drivers/net/wireless/rockchip_wlan/rtl8821cu/Makefile
+++ b/drivers/net/wireless/rockchip_wlan/rtl8821cu/Makefile
@@ -92,7 +92,7 @@ CONFIG_RTW_UP_MAPPING_RULE = tos
CONFIG_RTW_MBO = n
########################## Android ###########################
# CONFIG_RTW_ANDROID - 0: no Android, 4/5/6/7/8/9/10/11 : Android version
-CONFIG_RTW_ANDROID = 0
+CONFIG_RTW_ANDROID = 6
ifeq ($(shell test $(CONFIG_RTW_ANDROID) -gt 0; echo $$?), 0)
EXTRA_CFLAGS += -DCONFIG_RTW_ANDROID=$(CONFIG_RTW_ANDROID)
@@ -102,7 +102,7 @@ endif
CONFIG_RTW_DEBUG = y
# default log level is _DRV_INFO_ = 4,
# please refer to "How_to_set_driver_debug_log_level.doc" to set the available level.
-CONFIG_RTW_LOG_LEVEL = 4
+CONFIG_RTW_LOG_LEVEL = 2
# enable /proc/net/rtlxxxx/ debug interfaces
CONFIG_PROC_DEBUG = y
@@ -135,7 +135,7 @@ CONFIG_LAYER2_ROAMING = y
#bit0: ROAM_ON_EXPIRED, #bit1: ROAM_ON_RESUME, #bit2: ROAM_ACTIVE
CONFIG_ROAMING_FLAG = 0x3
###################### Platform Related #######################
-CONFIG_PLATFORM_I386_PC = y
+CONFIG_PLATFORM_I386_PC = n
CONFIG_PLATFORM_ANDROID_X86 = n
CONFIG_PLATFORM_ANDROID_INTEL_X86 = n
CONFIG_PLATFORM_JB_X86 = n
@@ -161,6 +161,7 @@ CONFIG_PLATFORM_ARM_TCC8930_JB42 = n
CONFIG_PLATFORM_ARM_RK2818 = n
CONFIG_PLATFORM_ARM_RK3066 = n
CONFIG_PLATFORM_ARM_RK3188 = n
+CONFIG_PLATFORM_ARM_RK3288 = y
CONFIG_PLATFORM_ARM_URBETTER = n
CONFIG_PLATFORM_ARM_TI_PANDA = n
CONFIG_PLATFORM_MIPS_JZ4760 = n
@@ -1712,6 +1713,23 @@ KSRC := /home/android_sdk/Rockchip/Rk3188/kernel
MODULE_NAME := wlan
endif
+ifeq ($(CONFIG_PLATFORM_ARM_RK3288), y)
+EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_ROCKCHIPS
+# default setting for Android 4.1, 4.2, 4.3, 4.4
+EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT
+EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE
+# default setting for Power control
+EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC
+ifeq ($(CONFIG_SDIO_HCI), y)
+EXTRA_CFLAGS += -DRTW_SUPPORT_PLATFORM_SHUTDOWN
+endif
+# default setting for Special function
+ARCH := arm
+CROSS_COMPILE := /media/hdd1/wugt/rk3288-android6.0-sdk/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
+KSRC := /media/hdd1/wugt/rk3288-android6.0-sdk/kernel
+MODULE_NAME := wlan
+endif
+
ifeq ($(CONFIG_PLATFORM_ARM_RK3066), y)
EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_RK3066
EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC
除了wifi驱动外,还需要更新rfkill驱动。
diff --git a/drivers/net/wireless/rockchip_wlan/wifi_sys/rkwifi_sys_iface.c b/drivers/net/wireless/rockchip_wlan/wifi_sys/rkwifi_sys_iface.c
index 58112a9..f7245d6 100755
--- a/drivers/net/wireless/rockchip_wlan/wifi_sys/rkwifi_sys_iface.c
+++ b/drivers/net/wireless/rockchip_wlan/wifi_sys/rkwifi_sys_iface.c
@@ -81,6 +81,11 @@ static ssize_t wifi_chip_read(struct class *cls, struct class_attribute *attr, c
count = sprintf(_buf, "%s", "RTL8188EU");
printk("Current WiFi chip is RTL8188EU.\n");
}
+
+ if(type == WIFI_RTL8821CU) {
+ count = sprintf(_buf, "%s", "RTL8821CU");
+ printk("Current WiFi chip is RTL8821CU.\n");
+ }
if(type == WIFI_RTL8723BS) {
count = sprintf(_buf, "%s", "RTL8723BS");
diff --git a/include/linux/rfkill-wlan.h b/include/linux/rfkill-wlan.h
index 6015bf4..041353f 100755
--- a/include/linux/rfkill-wlan.h
+++ b/include/linux/rfkill-wlan.h
@@ -57,6 +57,7 @@ enum {
WIFI_AP6493,
WIFI_AP6XXX_SERIES,
WIFI_RTL8188EU,
+ WIFI_RTL8821CU,
WIFI_RTL8192DU,
WIFI_RTL8723AS,
WIFI_RTL8723BS,
diff --git a/net/rfkill/rfkill-wlan.c b/net/rfkill/rfkill-wlan.c
index 55b8b5f..4f5d82c 100755
--- a/net/rfkill/rfkill-wlan.c
+++ b/net/rfkill/rfkill-wlan.c
@@ -126,6 +126,8 @@ int get_wifi_chip_type(void)
type = WIFI_AP6493;
} else if (strcmp(wifi_chip_type_string, "rtl8188eu") == 0) {
type = WIFI_RTL8188EU;
+ } else if (strcmp(wifi_chip_type_string, "rtl8821cu") == 0) {
+ type = WIFI_RTL8821CU;
} else if (strcmp(wifi_chip_type_string, "rtl8192du") == 0) {
type = WIFI_RTL8192DU;
} else if (strcmp(wifi_chip_type_string, "rtl8723as") == 0) {
bt
接下来是蓝牙驱动,由于sdk默认不支持RTL8821CU, 所以需要手动添加相关配置。
--- a/drivers/bluetooth/rtk_btusb.c
+++ b/drivers/bluetooth/rtk_btusb.c
@@ -70,7 +70,7 @@
#define CMD_HDR_LEN sizeof(struct hci_command_hdr)
#define EVT_HDR_LEN sizeof(struct hci_event_hdr)
#define CMD_CMP_LEN sizeof(struct hci_ev_cmd_complete)
-#define RTK_PATCH_LENGTH_MAX 1024*24
+#define RTK_PATCH_LENGTH_MAX 1024*36
static spinlock_t queue_lock;
enum rtk_endpoit {
@@ -145,6 +145,8 @@ static patch_info fw_patch_table[] = {
{ 0xb720, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723bu_config", NULL, 0 }, /* RTL8723BU */
{ 0xb72A, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723bu_config", NULL, 0 }, /* RTL8723BU */
+{ 0xB820, 0x8821, 0, 0, "mp_rtl8821c_fw", "rtl8821c_fw", "rtl8821c_config", NULL, 0 }, /* RTL8821CU */
+{ 0xC820, 0x8821, 0, 0, "mp_rtl8821c_fw", "rtl8821c_fw", "rtl8821c_config", NULL, 0 }, /* RTL8821CU */
{ 0xb728, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 }, /* RTL8723BE for LC */
{ 0xb723, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 }, /* RTL8723BE */
{ 0xb72B, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 }, /* RTL8723BE */
diff --git a/drivers/bluetooth/rtk_btusb.h b/drivers/bluetooth/rtk_btusb.h
index 5f5e53a..f71d7b1 100755
--- a/drivers/bluetooth/rtk_btusb.h
+++ b/drivers/bluetooth/rtk_btusb.h
@@ -127,6 +127,7 @@ struct rtk_bt_vendor_config{
#define ROM_LMP_8723a0x1200
#define ROM_LMP_8723b0x8723
#define ROM_LMP_8821a0X8821
+#define ROM_LMP_8821c0X8821
#define ROM_LMP_8761a0X8761
#define ROM_LMP_8703a0x8723
#define ROM_LMP_8763a0x8763
@@ -149,6 +150,8 @@ uint16_t project_id[] = {
ROM_LMP_8703b,
ROM_LMP_8723c,
ROM_LMP_8822b,
+ ROM_LMP_NONE,
+ ROM_LMP_8821c,
ROM_LMP_NONE
};
struct rtk_eversion_evt {
值得注意的是:
rtk_usb
驱动配置的最大fw size为24k, 而 RTL8821CU 的 FW 约 30k, 所以需要修改最大值为 36k- 添加
project_id
时,通过debug信息知道 RTL8821CU 对应的 ID 为 10,所以需要修改枚举列表,将 RTL8821CU 放置到第 10 个位置 - 通过设置
DBG_FLAG
可以打开调试信息
vendor
vendor 目录需要添加 RTL8821CU 所需的fw和config文件。
rockchip/common/bluetooth/bluetooth.mk| 1 +
rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/device-rtl.mk | 4 ++++
rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_config | Bin 0 -> 14 bytes
rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_fw | Bin 0 -> 50344 bytes
4 files changed, 5 insertions(+)
diff --git a/rockchip/common/bluetooth/bluetooth.mk b/rockchip/common/bluetooth/bluetooth.mk
index 0f6bde8..1dafdcc 100755
--- a/rockchip/common/bluetooth/bluetooth.mk
+++ b/rockchip/common/bluetooth/bluetooth.mk
@@ -12,6 +12,7 @@ $(call inherit-product-if-exists, $(LOCAL_PATH)/realtek/firmware/usb/rtl8723b/de
$(call inherit-product-if-exists, $(LOCAL_PATH)/realtek/firmware/usb/rtl8703b/device-rtl.mk)
$(call inherit-product-if-exists, $(LOCAL_PATH)/realtek/firmware/usb/rtl8761a/device-rtl.mk)
$(call inherit-product-if-exists, $(LOCAL_PATH)/realtek/firmware/usb/rtl8821a/device-rtl.mk)
+$(call inherit-product-if-exists, $(LOCAL_PATH)/realtek/firmware/usb/rtl8821c/device-rtl.mk)
$(call inherit-product-if-exists, $(LOCAL_PATH)/realtek/firmware/usb/rtl8822b/device-rtl.mk)
$(call inherit-product-if-exists, $(LOCAL_PATH)/realtek/firmware/uart/rtlbtfw_cfg.mk)
diff --git a/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/device-rtl.mk b/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/device-rtl.mk
new file mode 100755
index 0000000..440034c
--- /dev/null
+++ b/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/device-rtl.mk
@@ -0,0 +1,4 @@
+RTK_BT_FIRMWARE_DIR := rtl8821c
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/$(RTK_BT_FIRMWARE_DIR)_fw:system/etc/firmware/rtl8821c_fw \
+ $(LOCAL_PATH)/$(RTK_BT_FIRMWARE_DIR)_config:system/etc/firmware/rtl8821c_config
diff --git a/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_config b/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_config
new file mode 100755
index 0000000..cbec41e
Binary files /dev/null and b/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_config differ
diff --git a/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_fw b/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_fw
new file mode 100755
index 0000000..bc0df07
Binary files /dev/null and b/rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/rtl8821c_fw differ
此外,还要把 wifi 驱动 RTL8821CU.ko 放置到 rockchip/common/wifi/modules/
目录。
hci tools
如果要添加 hci 工具,需要添加以下patch. 这样可以将 hciconfig, hcitool, hcidump 等工具集成到安卓系统。
diff --git a/rockchip/common/rftesttool/broadcom/broadcom.mk b/rockchip/common/rftesttool/broadcom/broadcom.mk
index 8819218..4c50604 100644
--- a/rockchip/common/rftesttool/broadcom/broadcom.mk
+++ b/rockchip/common/rftesttool/broadcom/broadcom.mk
@@ -1,8 +1,10 @@
+ifneq ($(strip $(TARGET_BOARD_PLATFORM)), rk3288)
$(call inherit-product-if-exists, $(LOCAL_PATH)/app/app.mk)
MFG_FWS := $(shell ls $(LOCAL_PATH)/mfg)
PRODUCT_COPY_FILES += \
$(foreach file, $(MFG_FWS), $(LOCAL_PATH)/mfg/$(file):system/etc/firmware/mfg/$(file))
+endif
EXE_FILES := $(shell ls $(LOCAL_PATH)/bin)
PRODUCT_COPY_FILES += \
diff --git a/rockchip/common/rftesttool/rftesttool.mk b/rockchip/common/rftesttool/rftesttool.mk
index bed8945..1012e91 100644
--- a/rockchip/common/rftesttool/rftesttool.mk
+++ b/rockchip/common/rftesttool/rftesttool.mk
@@ -3,4 +3,6 @@ PRODUCT_PACKAGES += \
RFTestTool
$(call inherit-product-if-exists, $(LOCAL_PATH)/broadcom/broadcom.mk)
+else ifeq ($(strip $(TARGET_BOARD_PLATFORM)), rk3288)
+$(call inherit-product-if-exists, $(LOCAL_PATH)/broadcom/broadcom.mk)
endif
init.rc
最后,在 device/rockchip/rk3288/init.rc
文件中添加wifi驱动加载的指令。
diff --git a/init.rc b/init.rc
index 90a0b9e..e4285c3 100644
--- a/init.rc
+++ b/init.rc
@@ -463,6 +463,8 @@ on boot
chown root radio /proc/cmdline
insmod /drmboot.ko
+ insmod /system/lib/modules/8188eu.ko
+ insmod /system/lib/modules/8821cu.ko
# export power io of extend screen and set the default value
write /sys/class/gpio/export 224
以上修改全部完成后,完整编译固件即可打开wifi和蓝牙了。
注意事项
- wifi驱动需要在kernel目录通过
make modules
得到 - rtk_usb 驱动使能 DBG_FLAG 可以打印更多调试信息
版权声明:本博客所有文章除特殊声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明出处 litreily的博客!