1.蓝牙驱动

This commit is contained in:
payton 2023-12-12 19:22:56 +08:00
parent 5522667d3b
commit 721d4eefee
9 changed files with 5230 additions and 13 deletions

View File

@ -670,12 +670,9 @@ CONFIG_BT_DEBUGFS=y
# Bluetooth device drivers
#
# CONFIG_BT_HCIBTUSB is not set
CONFIG_BT_HCIBTUSB_RTLBTUSB=m
# CONFIG_BT_HCIBTSDIO is not set
CONFIG_BT_HCIUART=y
CONFIG_BT_HCIUART_H4=y
# CONFIG_BT_HCIUART_BCSP is not set
CONFIG_BT_HCIUART_RTKH5=y
# CONFIG_BT_HCIUART_LL is not set
# CONFIG_BT_HCIUART is not set
# CONFIG_BT_HCIBCM203X is not set
# CONFIG_BT_HCIBPA10X is not set
# CONFIG_BT_HCIBFUSB is not set

View File

@ -13,6 +13,16 @@ config BT_HCIBTUSB
Say Y here to compile support for Bluetooth USB devices into the
kernel or say M to compile it as module (btusb).
config BT_HCIBTUSB_RTLBTUSB
tristate "Realtek HCI USB driver support
depends on USB
help
Realtek Bluetooth HCI USB driver.
This driver is required if you want to use Realtek Bluetooth
device with USB interface.
Say Y here to compile support for Bluetooth USB devices into the
kernel or say M to compile it as module (rtk_btusb).
config BT_HCIBTSDIO
tristate "HCI SDIO driver"
depends on MMC

View File

@ -1,8 +1,22 @@
ifneq ($(KERNELRELEASE),)
obj-m := hci_uart.o
hci_uart-y := hci_ldisc.o hci_h4.o hci_rtk_h5.o rtk_coex.o
#EXTRA_CFLAGS += -DDEBUG
CONFIG_BTUSB_AUTOSUSPEND = n
CONFIG_BTUSB_WAKEUP_HOST = n
CONFIG_BTCOEX = y
ifeq ($(CONFIG_BTUSB_AUTOSUSPEND), y)
EXTRA_CFLAGS += -DCONFIG_BTUSB_AUTOSUSPEND
endif
ifeq ($(CONFIG_BTUSB_WAKEUP_HOST), y)
EXTRA_CFLAGS += -DCONFIG_BTUSB_WAKEUP_HOST
endif
ifeq ($(CONFIG_BTCOEX), y)
EXTRA_CFLAGS += -DCONFIG_BTCOEX
endif
ifneq ($(KERNELRELEASE),)
obj-m := rtk_btusb.o
rtk_btusb-y = rtk_coex.o rtk_misc.o rtk_bt.o
else
PWD := $(shell pwd)
KVER := $(shell uname -r)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,151 @@
/*
*
* 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/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/skbuff.h>
#include <linux/errno.h>
#include <linux/usb.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/version.h>
#include <linux/pm_runtime.h>
#include <linux/firmware.h>
#include <linux/suspend.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci.h>
/* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */
#define HCI_VERSION_CODE LINUX_VERSION_CODE
#ifdef CONFIG_BTCOEX
#define BTCOEX
#endif
/***********************************
** Realtek - For rtk_btusb driver **
***********************************/
#ifdef CONFIG_BTUSB_WAKEUP_HOST
#define BTUSB_WAKEUP_HOST
#endif
#define URB_CANCELING_DELAY_MS 10 // Added by Realtek
#if HCI_VERSION_CODE > KERNEL_VERSION(2, 6, 33)
#define HDEV_BUS hdev->bus
#else
#define HDEV_BUS hdev->type
#endif
#if HCI_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
#define NUM_REASSEMBLY 3
#endif
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
#define GET_DRV_DATA(x) hci_get_drvdata(x)
#else
#define GET_DRV_DATA(x) x->driver_data
#endif
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
#define SCO_NUM hdev->conn_hash.sco_num
#else
#define SCO_NUM hci_conn_num(hdev, SCO_LINK)
#endif
int patch_add(struct usb_interface *intf);
void patch_remove(struct usb_interface *intf);
int download_patch(struct usb_interface *intf);
int set_btoff(struct usb_interface *intf);
void print_event(struct sk_buff *skb);
void print_command(struct sk_buff *skb);
void print_acl(struct sk_buff *skb, int dataOut);
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb);
#else
int btusb_send_frame(struct sk_buff *skb);
#endif
#define BTUSB_MAX_ISOC_FRAMES 10
#define BTUSB_INTR_RUNNING 0
#define BTUSB_BULK_RUNNING 1
#define BTUSB_ISOC_RUNNING 2
#define BTUSB_SUSPENDING 3
#define BTUSB_DID_ISO_RESUME 4
#define BTUSB_USE_ALT3_FOR_WBS 15
struct btusb_data {
struct hci_dev *hdev;
struct usb_device *udev;
struct usb_interface *intf;
struct usb_interface *isoc;
spinlock_t lock;
unsigned long flags;
struct work_struct work;
struct work_struct waker;
struct usb_anchor tx_anchor;
struct usb_anchor intr_anchor;
struct usb_anchor bulk_anchor;
struct usb_anchor isoc_anchor;
struct usb_anchor deferred;
int tx_in_flight;
spinlock_t txlock;
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
spinlock_t rxlock;
struct sk_buff *evt_skb;
struct sk_buff *acl_skb;
struct sk_buff *sco_skb;
#endif
struct usb_endpoint_descriptor *intr_ep;
struct usb_endpoint_descriptor *bulk_tx_ep;
struct usb_endpoint_descriptor *bulk_rx_ep;
struct usb_endpoint_descriptor *isoc_tx_ep;
struct usb_endpoint_descriptor *isoc_rx_ep;
__u8 cmdreq_type;
unsigned int sco_num;
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
unsigned int air_mode;
bool usb_alt6_packet_flow;
#endif
int isoc_altsetting;
int suspend_count;
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
int (*recv_bulk) (struct btusb_data * data, void *buffer, int count);
#endif
struct notifier_block pm_notifier;
struct notifier_block shutdown_notifier;
void *context;
};

View File

@ -57,10 +57,10 @@
#define RTK_VERSION "1.2"
#define RTKBT_DBG(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "\n" , ## arg)
#define RTKBT_DBG(fmt, arg...) printk(KERN_DEBUG "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)
#define RTKBT_ERR(fmt, arg...) printk(KERN_ERR "rtk_btcoex: " fmt "\n", ## arg)
static struct rtl_coex_struct btrtl_coex;
@ -2922,6 +2922,11 @@ static void check_profileinfo_cmd(void)
profileinfo_buf);
}
static void rtl_cmd_work(struct work_struct *work)
{
check_profileinfo_cmd();
}
void rtk_btcoex_open(struct hci_dev *hdev)
{
if (test_and_set_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
@ -2935,6 +2940,7 @@ void rtk_btcoex_open(struct hci_dev *hdev)
//struct rtl_btinfo_ctl ctl;
INIT_DELAYED_WORK(&btrtl_coex.fw_work, (void *)rtl_ev_work);
INIT_DELAYED_WORK(&btrtl_coex.cmd_work, rtl_cmd_work);
#ifdef RTB_SOFTWARE_MAILBOX
#ifdef RTK_COEX_OVER_SYMBOL
INIT_WORK(&rtw_work, rtw_work_func);
@ -2966,7 +2972,8 @@ void rtk_btcoex_open(struct hci_dev *hdev)
#endif
rtkbt_coexmsg_send(invite_req, sizeof(invite_req));
#endif
check_profileinfo_cmd();
queue_delayed_work(btrtl_coex.fw_wq, &btrtl_coex.cmd_work,
msecs_to_jiffies(10));
/* Just for test */
//ctl.polling_enable = 1;
//ctl.polling_time = 1;
@ -3010,6 +3017,7 @@ void rtk_btcoex_close(void)
cancel_delayed_work_sync(&btrtl_coex.fw_work);
cancel_delayed_work_sync(&btrtl_coex.l2_work);
cancel_delayed_work_sync(&btrtl_coex.cmd_work);
flush_connection_hash(&btrtl_coex);
flush_profile_hash(&btrtl_coex);

View File

@ -27,7 +27,7 @@
#define BTRTL_HCIUSB 0
#define BTRTL_HCIUART 1
#define BTRTL_HCI_IF BTRTL_HCIUART
#define BTRTL_HCI_IF BTRTL_HCIUSB
#define TRUE 1
#define FALSE 0
@ -250,6 +250,7 @@ struct rtl_coex_struct {
struct workqueue_struct *timer_wq;
struct delayed_work fw_work;
struct delayed_work l2_work;
struct delayed_work cmd_work;
#ifdef RTB_SOFTWARE_MAILBOX
struct sock *sk;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,134 @@
/*
*
* Realtek Bluetooth USB download firmware 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/version.h>
#include <linux/pm_runtime.h>
#include <linux/usb.h>
#include <linux/suspend.h>
/* Download LPS patch when host suspends or power off
* LPS patch name: lps_rtl8xxx_fw
* LPS config name: lps_rtl8xxx_config
* Download normal patch when host resume or power on */
/* #define RTKBT_SWITCH_PATCH */
/* RTKBT Power-on for sideband wake-up by LE Advertising from Remote. */
/* Note that it's necessary to apply TV FW Patch. */
/* #define RTKBT_SUSPEND_WAKEUP */
/* #define RTKBT_SHUTDOWN_WAKEUP */
#define RTKBT_POWERKEY_WAKEUP
/* RTKBT Power-on Whitelist for sideband wake-up by LE Advertising from Remote.
* Note that it's necessary to apply TV FW Patch. */
/* #define RTKBT_TV_POWERON_WHITELIST */
#if 1
#define RTKBT_DBG(fmt, arg...) printk(KERN_DEBUG "rtk_btusb: " fmt "\n" , ## arg)
#define RTKBT_INFO(fmt, arg...) printk(KERN_INFO "rtk_btusb: " fmt "\n" , ## arg)
#define RTKBT_WARN(fmt, arg...) printk(KERN_WARNING "rtk_btusb: " fmt "\n", ## arg)
#else
#define RTKBT_DBG(fmt, arg...)
#endif
#if 1
#define RTKBT_ERR(fmt, arg...) printk(KERN_ERR "rtk_btusb: " fmt "\n" , ## arg)
#else
#define RTKBT_ERR(fmt, arg...)
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 33)
#define USB_RPM
#endif
#define CONFIG_NEEDS_BINDING
/* If module is still powered when kernel suspended, there is no re-binding. */
#ifdef RTKBT_SWITCH_PATCH
#undef CONFIG_NEEDS_BINDING
#endif
/* USB SS */
#if (defined CONFIG_BTUSB_AUTOSUSPEND) && (defined USB_RPM)
#define BTUSB_RPM
#endif
#define PRINT_CMD_EVENT 0
#define PRINT_ACL_DATA 0
extern int patch_add(struct usb_interface *intf);
extern void patch_remove(struct usb_interface *intf);
extern int download_patch(struct usb_interface *intf);
extern void print_event(struct sk_buff *skb);
extern void print_command(struct sk_buff *skb);
extern void print_acl(struct sk_buff *skb, int dataOut);
#if defined RTKBT_SWITCH_PATCH || defined RTKBT_TV_POWERON_WHITELIST
int __rtk_send_hci_cmd(struct usb_device *udev, u8 *buf, u16 size);
#endif
#ifdef RTKBT_SWITCH_PATCH
#define RTLBT_CLOSE (1 << 0)
struct api_context {
u32 flags;
struct completion done;
int status;
};
int download_special_patch(struct usb_interface *intf, const char *special_name);
#endif
int setup_btrealtek_flag(struct usb_interface *intf, struct hci_dev *hdev);
enum {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
REALTEK_ALT6_CONTINUOUS_TX_CHIP,
#endif
__REALTEK_NUM_FLAGS,
};
struct btrealtek_data {
DECLARE_BITMAP(flags, __REALTEK_NUM_FLAGS);
};
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
static inline void *hci_get_priv(struct hci_dev *hdev)
{
return (char *)hdev + sizeof(*hdev);
}
#endif
#define btrealtek_set_flag(hdev, nr) \
do { \
struct btrealtek_data *realtek = hci_get_priv((hdev)); \
set_bit((nr), realtek->flags); \
} while (0)
#define btrealtek_get_flag(hdev) \
(((struct btrealtek_data *)hci_get_priv(hdev))->flags)
#define btrealtek_test_flag(hdev, nr) test_bit((nr), btrealtek_get_flag(hdev))
#if defined RTKBT_SUSPEND_WAKEUP || defined RTKBT_SHUTDOWN_WAKEUP || defined RTKBT_SWITCH_PATCH
int set_scan(struct usb_interface *intf);
#endif