/*
*
* Realtek Bluetooth USB driver
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <linux/dcache.h>
#include <linux/version.h>
#include <net/sock.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include "rtk_coex.h"
/* Software coex message can be sent to and receive from WiFi driver by
* UDP socket or exported symbol */
/* #define RTK_COEX_OVER_SYMBOL */
#if BTRTL_HCI_IF == BTRTL_HCIUSB
#include <linux/usb.h>
#include "rtk_bt.h"
#undef RTKBT_DBG
#undef RTKBT_INFO
#undef RTKBT_WARN
#undef RTKBT_ERR
#elif BTRTL_HCI_IF == BTRTL_HCIUART
/* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */
#define HCI_VERSION_CODE LINUX_VERSION_CODE
#else
#error "Please set type of HCI interface"
#endif
#define RTK_VERSION "1.2"
#define RTKBT_DBG(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "\n" , ## arg)
#define RTKBT_INFO(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "\n" , ## arg)
#define RTKBT_WARN(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "\n", ## arg)
#define RTKBT_ERR(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "\n", ## arg)
static struct rtl_coex_struct btrtl_coex;
#ifdef RTB_SOFTWARE_MAILBOX
#ifdef RTK_COEX_OVER_SYMBOL
static struct sk_buff_head rtw_q;
static struct workqueue_struct *rtw_wq;
static struct work_struct rtw_work;
static u8 rtw_coex_on;
#endif
#endif
#define is_profile_connected(profile) ((btrtl_coex.profile_bitmap & BIT(profile)) > 0)
#define is_profile_busy(profile) ((btrtl_coex.profile_status & BIT(profile)) > 0)
#ifdef RTB_SOFTWARE_MAILBOX
static void rtk_handle_event_from_wifi(uint8_t * msg);
#endif
static int rtl_alloc_buff(struct rtl_coex_struct *coex)
{
struct rtl_hci_ev *ev;
struct rtl_l2_buff *l2;
int i;
int order;
unsigned long addr;
unsigned long addr2;
int ev_size;
int l2_size;
int n;
spin_lock_init(&coex->buff_lock);
INIT_LIST_HEAD(&coex->ev_used_list);
INIT_LIST_HEAD(&coex->ev_free_list);
INIT_LIST_HEAD(&coex->l2_used_list);
INIT_LIST_HEAD(&coex->l2_free_list);
n = NUM_RTL_HCI_EV * sizeof(struct rtl_hci_ev);
ev_size = ALIGN(n, sizeof(unsigned long));
n = L2_MAX_PKTS * sizeof(struct rtl_l2_buff);
l2_size = ALIGN(n, sizeof(unsigned long));
RTKBT_DBG("alloc buffers %d, %d for ev and l2", ev_size, l2_size);
order = get_order(ev_size + l2_size);
addr = __get_free_pages(GFP_KERNEL, order);
if (!addr) {
RTKBT_ERR("failed to alloc buffers for ev and l2.");
return -ENOMEM;
}
memset((void *)addr, 0, ev_size + l2_size);
coex->pages_addr = addr;
coex->buff_size = ev_size + l2_size;
ev = (struct rtl_hci_ev *)addr;
for (i = 0; i < NUM_RTL_HCI_EV; i++) {
list_add_tail(&ev->list, &coex->ev_free_list);
ev++;
}
addr2 = addr + ev_size;
l2 = (struct rtl_l2_buff *)addr2;
for (i = 0; i < L2_MAX_PKTS; i++) {
list_add_tail(&l2->list, &coex->l2_free_list);
l2++;
}
return 0;
}
static void rtl_free_buff(struct rtl_coex_struct *coex)
{
struct rtl_hci_ev *ev;
struct rtl_l2_buff *l2;
unsigned long flags;
spin_lock_irqsave(&coex->buff_lock, flags);
while (!list_empty(&coex->ev_used_list)) {
ev = list_entry(coex->ev_used_list.next, struct rtl_hci_ev,
list);
list_del(&ev->list);
}
while (!list_empty(&coex->ev_free_list)) {
ev = list_entry(coex->ev_free_list.next, struct rtl_hci_ev,
list);
list_del(&ev->list);
}
while (!list_empty(&coex->l2_used_list)) {
l2 = list_entry(coex->l2_used_list.next, struct rtl_l2_buff,
list);
list_del(&l2->list);
}
while (!list_empty(&coex->l2_free_list)) {
l2 = list_entry(coex->l2_free_list.next, struct rtl_l2_buff,
list);
list_del(&l2->list);
}
spin_unlock_irqrestore(&coex->buff_lock, flags);
if (coex->buff_size > 0) {
free_pages(coex->pages_addr, get_order(coex->buff_size));
coex->pages_addr = 0;
coex->buff_size = 0;
}
}
static struct rtl_hci_ev *rtl_ev_node_get(struct rtl_coex_struct *coex)
{
struct rtl_hci_ev *ev;
unsigned long flags;
if (!coex->buff_size)
return NULL;
spin_lock_irqsave(&coex->buff_lock, flags);
if (!list_empty(&coex->ev_free_list)) {
ev = list_entry(coex->ev_free_list.next, struct rtl_hci_ev,
list);
list_del(&ev->list);
} else
ev = NULL;
spin_unlock_irqrestore(&coex->buff_lock, flags);
return ev;
}
static int rtl_ev_node_to_used(struct rtl_coex_struct *coex,
struct rtl_hci_ev *ev)
{
unsigned long flags;
spin_lock_irqsave(&coex->buff_lock, flags);
list_add_tail(&ev->list, &coex->ev_used_list);
spin_unlock_irqrestore(&coex->buff_lock, flags);
return 0;
}
static struct rtl_l2_buff *rtl_l2_node_get(struct rtl_coex_struct *coex)
{
struct rtl_l2_buff *l2;
unsigned long flags;
if (!coex->buff_size)
return NULL;
spin_lock_irqsave(&coex->buff_lock, flags);
if(!list_empty(&coex->l2_free_list)) {
l2 = list_entry(coex->l2_free_list.next, struct rtl_l2_buff,
list);
list_del(&l2->list);
} else
l2 = NULL;
spin_unlock_irqrestore(&coex->buff_lock, flags);
return l2;
}
static int rtl_l2_node_to_used(struct rtl_coex_struct *coex,
struct rtl_l2_buff *l2)
{
unsigned long flags;
spin_lock_irqsave(&coex->buff_lock, flags);
list_add_tail(&l2->list, &coex->l2_used_list);
spin_unlock_irqrestore(&coex->buff_lock, flags);
return 0;
}
static int8_t psm_to_profile_index(uint16_t psm)
{
switch (psm) {
case PSM_AVCTP:
case PSM_SDP:
return -1; //ignore
case PSM_HID:
case PSM_HID_INT:
return profile_hid;
case PSM_AVDTP:
return profile_a2dp;
case PSM_PAN:
case PSM_OPP:
case PSM_FTP:
case PSM_BIP:
case PSM_RFCOMM:
return profile_pan;
default:
return profile_pan;
}
}
static rtk_prof_info *find_by_psm(u16 psm)
{
struct list_head *head = &btrtl_coex.profile_list;
struct list_head *iter = NULL;
struct list_head *temp = NULL;
rtk_prof_info *desc = NULL;
list_for_each_safe(iter, temp, head) {
desc = list_entry(iter, rtk_prof_info, list);
if (desc->psm == psm)
return desc;
}
return NULL;
}
static void rtk_check_setup_timer(int8_t profile_index)
{
if (profile_index == profile_a2dp) {
btrtl_coex.a2dp_packet_count = 0;
btrtl_coex.a2dp_count_timer.expires =
jiffies + msecs_to_jiffies(1000);
mod_timer(&btrtl_coex.a2dp_count_timer,
btrtl_coex.a2dp_count_timer.expires);
}
if (profile_index == profile_pan) {
btrtl_coex.pan_packet_count = 0;
btrtl_coex.pan_count_timer.expires =
jiffies + msecs_to_jiffies(1000);
mod_timer(&btrtl_coex.pan_count_timer,
btrtl_coex.pan_count_timer.expires);
}
/* hogp & voice share one timer now */
if ((profile_index == profile_hogp) || (profile_index == profile_voice)) {
if ((0 == btrtl_coex.profile_refcount[profile_hogp])
&& (0 == btrtl_coex.profile_refcount[profile_voice])) {
btrtl_coex.hogp_packet_count = 0;
btrtl_coex.voice_packet_count = 0;
btrtl_coex.hogp_count_timer.expires =
jiffies + msecs_to_jiffies(1000);
mod_timer(&btrtl_coex.hogp_count_timer,
btrtl_coex.hogp_count_timer.expires);
}
}
}
static void rtk_check_del_timer(int8_t profile_index)
{
if (profile_a2dp == profile_index) {
btrtl_coex.a2dp_packet_count = 0;
del_timer_sync(&btrtl_coex.a2
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
里面包含了RTL8723BS所用到的所有的蓝牙驱动程序,包含rtk_hciattach工具、HCI串口蓝牙驱动等。 RTL8723BS蓝牙驱动程序及其Makefile的配置主要涉及到驱动文件的添加、内核配置、设备树配置以及驱动编译等多个步骤。以下是一个概括性的指导,由于具体步骤可能因不同的硬件平台和Linux内核版本而异,因此在实际操作中可能需要根据具体情况进行调整。 rtk_hciattach是一个与蓝牙相关的工具,它专门针对Realtek(瑞昱)的蓝牙芯片设计,用于在Linux系统上将串行端口与蓝牙协议栈(Bluetooth Host Controller Interface, HCI)进行连接。这个工具在嵌入式系统和物联网(IoT)领域尤为重要,因为它允许开发者在这些系统中集成和调试蓝牙功能。 HCI_UART,即主机控制接口(Host Controller Interface)通过通用异步接收及发送接口(Universal Asynchronous Receive Transmitter,UART)进行通信,是蓝牙技术中一种重要的连接方式。HCI(Host Controller
资源推荐
资源详情
资源评论
收起资源包目录
rkwifibt.rar (46个子文件)
rkwifibt
RTL8723BS
rtl8723b_config 55B
rtl8723b_fw 50KB
bluetooth_uart_driver
hci_uart.ko 1.27MB
hci_h4.c 7KB
hci_uart.o 1.24MB
hci_ldisc.o 311KB
modules.order 84B
hci_ldisc.c 26KB
rtk_coex.o 391KB
.hci_rtk_h5.o.cmd 57KB
.hci_h4.o.cmd 57KB
Makefile 539B
.hci_uart.o.cmd 559B
.hci_uart.mod.cmd 530B
Kconfig 7KB
.hci_ldisc.o.cmd 57KB
.Module.symvers.cmd 344B
.hci_uart.ko.cmd 442B
hci_h4.o 275KB
rtk_coex.c 76KB
hci_uart.mod 334B
hci_rtk_h5.c 22KB
.rtk_coex.o.cmd 56KB
hci_uart.mod.o 39KB
.modules.order.cmd 300B
hci_uart.mod.c 587B
.hci_uart.mod.o.cmd 25KB
hci_uart.h 4KB
hci_rtk_h5.o 296KB
rtk_coex.h 11KB
Module.symvers 0B
Makefile 554B
rtk_hciattach
rtb_fwc.h 2KB
rtb_fwc.c 34KB
Makefile 417B
hciattach.c 12KB
rtb_fwc.o 43KB
hciattach_rtk.o 58KB
hciattach_h4.h 270B
hciattach.h 5KB
rtk_hciattach 106KB
hciattach.o 28KB
hciattach_rtk.c 47KB
fix_mac.patch 6KB
hciattach_h4.c 6KB
hciattach_h4.o 17KB
共 46 条
- 1
资源评论
Serein朔一
- 粉丝: 109
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 矢量控制入门 如果你买了一堆学习资料,学习半年甚至更久了,还不会写FOC,那不妨看看这里 首先声明,非开发版赠送的那类代码
- 深度学习|梯度下降法:误差最小化的权重参数
- 中优8675云动态人脸门禁机是一款功能丰富的门禁设备,广泛应用于各种需要门禁管理的场所 以下是关于中优8675云动态人脸门禁机
- 深度学习|激活函数:网络表达增强
- 中优8650动态人脸门禁机是一款功能丰富的门禁设备,具有双稳态功能,可实现刷脸一次门常开、再次刷脸门关闭的操作 以下是关于中
- NetAssist网络传输助手
- javascript的代码,获取当前页面的url
- 优8643动态人脸指纹门禁机是一种集成了动态人脸识别技术和指纹识别技术的门禁设备 以下是关于该门禁机的详细信息:
- 中优云门禁指纹机是一款智能门禁管理设备,支持指纹解锁方式,适用于社区物业、学校、企业等场所 以下是关于中优云门禁指纹机的详细介
- 中优A2双门门禁机使用说明 中优A2双门门禁机是一款功能丰富的门禁设备,支持多种开门方式 以下是其使用说明: 开门方式
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功