first commit
This commit is contained in:
20
external/cache/sources/rtk_hciattach/Makefile
vendored
Normal file
20
external/cache/sources/rtk_hciattach/Makefile
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
CFLAGS := -Wall -g
|
||||
CC := $(CROSS_COMPILE)gcc
|
||||
all: rtk_hciattach
|
||||
OBJS := hciattach.o hciattach_rtk.o hciattach_h4.o rtb_fwc.o
|
||||
|
||||
rtk_hciattach: $(OBJS)
|
||||
$(CROSS_COMPILE)gcc -o rtk_hciattach $(OBJS)
|
||||
|
||||
%.o: %.c
|
||||
$(CROSS_COMPILE)gcc -c $< -o $@ $(CFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) rtk_hciattach
|
||||
|
||||
tags: FORCE
|
||||
ctags -R
|
||||
find ./ -name "*.h" -o -name "*.c" -o -name "*.cc" -o -name "*.cpp" > cscope.files
|
||||
cscope -bkq -i cscope.files
|
||||
PHONY += FORCE
|
||||
FORCE:
|
||||
39
external/cache/sources/rtk_hciattach/Readme.txt
vendored
Normal file
39
external/cache/sources/rtk_hciattach/Readme.txt
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
The document describes how to support Realtek UART Bluetooth driver in Linux system.
|
||||
|
||||
The supported kernel version is 2.6.32 - 4.15
|
||||
|
||||
The default serial protocol of Realtek Bluetooth chip is Three-wire (H5) protocol
|
||||
with flow control on, parity even and internel 32k clock.
|
||||
|
||||
The default baud rate is 115200.
|
||||
|
||||
To support Three-wire (H5) protocol, you need to install Realtek hci_uart driver
|
||||
and rtk_hciattach tool.
|
||||
|
||||
1. make sure your UART setting is correct.
|
||||
host tx - controller rx
|
||||
host rx - controller tx
|
||||
host rts - controller cts
|
||||
host cts - ground
|
||||
NC - controller rts
|
||||
|
||||
2. Install Bluetooth kernel driver and rtk_hciattach tool
|
||||
$ sudo make install
|
||||
If you encounter an error like "depmod: ERROR: Bad version passed /lib/modules/...",
|
||||
please change the lines "depmod -a $(MDL_DIR)" to "depmod -a $(shell uname -r)"
|
||||
|
||||
3. Initialize Realtek Bluetooth chip by rtk_hciattach
|
||||
$ sudo rtk_hciattach -n -s 115200 ttyUSB0 rtk_h5
|
||||
|
||||
for H4 protocol chip
|
||||
$ sudo rtk_hciattach -n -s 115200 ttyUSB0 rtk_h4
|
||||
|
||||
Tips: ttyUSB0 is serial port name in your system, you should change it
|
||||
according to hardware such as ttyS0.
|
||||
|
||||
4. Uninstall
|
||||
$ sudo make uninstall
|
||||
|
||||
If you want to change the parameter such as baud rate and pcm settings, you
|
||||
should modify rtl8xxx_config file.
|
||||
|
||||
631
external/cache/sources/rtk_hciattach/hciattach.c
vendored
Normal file
631
external/cache/sources/rtk_hciattach/hciattach.c
vendored
Normal file
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include "hciattach.h"
|
||||
|
||||
#define RFKILL_NODE "/sys/class/rfkill/rfkill0/state"
|
||||
|
||||
#ifdef NEED_PPOLL
|
||||
#include "ppoll.h"
|
||||
#endif
|
||||
|
||||
/* #define SCHED_ENABLE */
|
||||
|
||||
#ifdef SCHED_ENABLE
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
struct uart_t {
|
||||
char *type;
|
||||
int m_id;
|
||||
int p_id;
|
||||
int proto;
|
||||
int init_speed;
|
||||
int speed;
|
||||
int flags;
|
||||
int pm;
|
||||
char *bdaddr;
|
||||
int (*init) (int fd, struct uart_t *u, struct termios *ti);
|
||||
int (*post) (int fd, struct uart_t *u, struct termios *ti);
|
||||
};
|
||||
|
||||
#define FLOW_CTL 0x0001
|
||||
#define ENABLE_PM 1
|
||||
#define DISABLE_PM 0
|
||||
|
||||
static volatile sig_atomic_t __io_canceled = 0;
|
||||
|
||||
static void sig_hup(int sig)
|
||||
{
|
||||
RS_INFO("signal hup.");
|
||||
}
|
||||
|
||||
static void sig_term(int sig)
|
||||
{
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
RS_INFO("signal int.");
|
||||
break;
|
||||
case SIGTERM:
|
||||
RS_INFO("signal term.");
|
||||
break;
|
||||
}
|
||||
__io_canceled = 1;
|
||||
}
|
||||
|
||||
static void sig_alarm(int sig)
|
||||
{
|
||||
RS_ERR("Initialization timed out.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int uart_speed(int s)
|
||||
{
|
||||
switch (s) {
|
||||
case 9600:
|
||||
return B9600;
|
||||
case 19200:
|
||||
return B19200;
|
||||
case 38400:
|
||||
return B38400;
|
||||
case 57600:
|
||||
return B57600;
|
||||
case 115200:
|
||||
return B115200;
|
||||
case 230400:
|
||||
return B230400;
|
||||
case 460800:
|
||||
return B460800;
|
||||
case 500000:
|
||||
return B500000;
|
||||
case 576000:
|
||||
return B576000;
|
||||
case 921600:
|
||||
return B921600;
|
||||
case 1000000:
|
||||
return B1000000;
|
||||
case 1152000:
|
||||
return B1152000;
|
||||
case 1500000:
|
||||
return B1500000;
|
||||
case 2000000:
|
||||
return B2000000;
|
||||
#ifdef B2500000
|
||||
case 2500000:
|
||||
return B2500000;
|
||||
#endif
|
||||
#ifdef B3000000
|
||||
case 3000000:
|
||||
return B3000000;
|
||||
#endif
|
||||
#ifdef B3500000
|
||||
case 3500000:
|
||||
return B3500000;
|
||||
#endif
|
||||
#ifdef B4000000
|
||||
case 4000000:
|
||||
return B4000000;
|
||||
#endif
|
||||
default:
|
||||
return B57600;
|
||||
}
|
||||
}
|
||||
|
||||
int set_speed(int fd, struct termios *ti, int speed)
|
||||
{
|
||||
if (cfsetospeed(ti, uart_speed(speed)) < 0)
|
||||
return -errno;
|
||||
|
||||
if (cfsetispeed(ti, uart_speed(speed)) < 0)
|
||||
return -errno;
|
||||
|
||||
if (tcsetattr(fd, TCSANOW, ti) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int realtek_init(int fd, struct uart_t *u, struct termios *ti)
|
||||
{
|
||||
|
||||
RS_INFO("Realtek Bluetooth init uart with init speed:%d, type:HCI UART %s",
|
||||
u->init_speed,
|
||||
(u->proto == HCI_UART_H4) ? "H4" : "H5");
|
||||
return rtb_init(fd, u->proto, u->speed, ti);
|
||||
}
|
||||
|
||||
static int realtek_post(int fd, struct uart_t *u, struct termios *ti)
|
||||
{
|
||||
RS_INFO("Realtek Bluetooth post process");
|
||||
return rtb_post(fd, u->proto, ti);
|
||||
}
|
||||
|
||||
struct uart_t uart[] = {
|
||||
{ "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, DISABLE_PM, NULL, NULL},
|
||||
|
||||
/* Realtek Bluetooth H4 */
|
||||
{ "rtk_h4", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, 0, DISABLE_PM, NULL, realtek_init, realtek_post },
|
||||
|
||||
/* Realtek Bluetooth H5 */
|
||||
{ "rtk_h5", 0x0000, 0x0000, HCI_UART_3WIRE, 115200,115200, 0, DISABLE_PM, NULL, realtek_init, realtek_post },
|
||||
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static struct uart_t * get_by_id(int m_id, int p_id)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; uart[i].type; i++) {
|
||||
if (uart[i].m_id == m_id && uart[i].p_id == p_id)
|
||||
return &uart[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct uart_t * get_by_type(char *type)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; uart[i].type; i++) {
|
||||
if (!strcmp(uart[i].type, type))
|
||||
return &uart[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize UART driver */
|
||||
static int init_uart(char *dev, struct uart_t *u, int send_break, int raw)
|
||||
{
|
||||
struct termios ti;
|
||||
int fd, i;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (raw)
|
||||
flags |= 1 << HCI_UART_RAW_DEVICE;
|
||||
|
||||
fd = open(dev, O_RDWR | O_NOCTTY);
|
||||
if (fd < 0) {
|
||||
RS_ERR("Can't open serial port, %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (tcgetattr(fd, &ti) < 0) {
|
||||
RS_ERR("Can't get port settings, %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
cfmakeraw(&ti);
|
||||
|
||||
ti.c_cflag |= CLOCAL;
|
||||
if (u->flags & FLOW_CTL)
|
||||
ti.c_cflag |= CRTSCTS;
|
||||
else
|
||||
ti.c_cflag &= ~CRTSCTS;
|
||||
|
||||
if (tcsetattr(fd, TCSANOW, &ti) < 0) {
|
||||
RS_ERR("Can't set port settings, %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set initial baudrate */
|
||||
if (set_speed(fd, &ti, u->init_speed) < 0) {
|
||||
RS_ERR("Can't set initial baud rate, %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (send_break) {
|
||||
tcsendbreak(fd, 0);
|
||||
usleep(500000);
|
||||
}
|
||||
|
||||
if (u->init && u->init(fd, u, &ti) < 0)
|
||||
return -1;
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
/* Set actual baudrate
|
||||
* There is no need to change baudrate after uart init
|
||||
* */
|
||||
/* if (set_speed(fd, &ti, u->speed) < 0) {
|
||||
* perror("Can't set baud rate");
|
||||
* return -1;
|
||||
* }
|
||||
*/
|
||||
|
||||
/* Set TTY to N_HCI line discipline */
|
||||
i = N_HCI;
|
||||
if (ioctl(fd, TIOCSETD, &i) < 0) {
|
||||
RS_ERR("Can't set line discipline %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags && ioctl(fd, HCIUARTSETFLAGS, flags) < 0) {
|
||||
RS_ERR("Can't set UART flags %d, %s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, HCIUARTSETPROTO, u->proto) < 0) {
|
||||
RS_ERR("Can't set device %d, %s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (u->post && u->post(fd, u, &ti) < 0)
|
||||
return -1;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int reset_bluetooth(void)
|
||||
{
|
||||
|
||||
int fd;
|
||||
char state[2];
|
||||
int result;
|
||||
|
||||
/* power off and power on BT */
|
||||
fd = open(RFKILL_NODE, O_RDWR);
|
||||
if (fd < 0) {
|
||||
RS_ERR("Cannot open %s, %d %s", RFKILL_NODE, errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
state[0] = '0';
|
||||
state[1] = '\0';
|
||||
result = write(fd, state, strlen(state) + 1);
|
||||
if (result != (strlen(state) + 1)) {
|
||||
RS_ERR("Cannot write 0 to rfkill state %d %s", errno,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
usleep(500000);
|
||||
|
||||
state[0] = '1';
|
||||
state[1] = '\0';
|
||||
result = write(fd, state, strlen(state) + 1);
|
||||
if (result != (strlen(state) + 1)) {
|
||||
RS_ERR("Cannot write 1 to rfkill state %d %s", errno,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
usleep(500000);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
RS_INFO("hciattach - HCI UART driver initialization utility");
|
||||
RS_INFO("Usage:");
|
||||
RS_INFO("\thciattach [-n] [-p] [-b] [-r] [-t timeout] [-s initial_speed] <tty> <type | id> [speed] [flow|noflow] [bdaddr]");
|
||||
RS_INFO("\thciattach -l");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct uart_t *u = NULL;
|
||||
int detach, printpid, raw, opt, i, n, ld, err;
|
||||
int to = 10;
|
||||
int init_speed = 0;
|
||||
int send_break = 0;
|
||||
pid_t pid;
|
||||
struct sigaction sa;
|
||||
struct pollfd p;
|
||||
sigset_t sigs;
|
||||
char dev[PATH_MAX];
|
||||
#ifdef SCHED_ENABLE
|
||||
struct sched_param sched_par;
|
||||
#endif
|
||||
|
||||
detach = 1;
|
||||
printpid = 0;
|
||||
raw = 0;
|
||||
|
||||
while ((opt=getopt(argc, argv, "bnpt:s:lr")) != EOF) {
|
||||
switch(opt) {
|
||||
case 'b':
|
||||
send_break = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
detach = 0;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
printpid = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
to = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
init_speed = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
for (i = 0; uart[i].type; i++) {
|
||||
RS_INFO("%-10s0x%04x,0x%04x", uart[i].type,
|
||||
uart[i].m_id, uart[i].p_id);
|
||||
}
|
||||
exit(0);
|
||||
|
||||
case 'r':
|
||||
raw = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
n = argc - optind;
|
||||
if (n < 2) {
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (n = 0; optind < argc; n++, optind++) {
|
||||
char *opt;
|
||||
|
||||
opt = argv[optind];
|
||||
|
||||
switch(n) {
|
||||
case 0:
|
||||
dev[0] = 0;
|
||||
if (!strchr(opt, '/'))
|
||||
strcpy(dev, "/dev/");
|
||||
strcat(dev, opt);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (strchr(argv[optind], ',')) {
|
||||
int m_id, p_id;
|
||||
sscanf(argv[optind], "%x,%x", &m_id, &p_id);
|
||||
u = get_by_id(m_id, p_id);
|
||||
} else {
|
||||
u = get_by_type(opt);
|
||||
}
|
||||
|
||||
if (!u) {
|
||||
RS_ERR("Unknown device type or id");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
u->speed = atoi(argv[optind]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (!strcmp("flow", argv[optind]))
|
||||
u->flags |= FLOW_CTL;
|
||||
else
|
||||
u->flags &= ~FLOW_CTL;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (!strcmp("sleep", argv[optind]))
|
||||
u->pm = ENABLE_PM;
|
||||
else
|
||||
u->pm = DISABLE_PM;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
u->bdaddr = argv[optind];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!u) {
|
||||
RS_ERR("Unknown device type or id");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
start:
|
||||
|
||||
#ifdef SCHED_ENABLE
|
||||
RS_INFO("Increase the priority of the process with set sched");
|
||||
memset(&sched_par, 0, sizeof(sched_par));
|
||||
sched_par.sched_priority = 99;
|
||||
err = sched_setscheduler(0, SCHED_FIFO, &sched_par);
|
||||
if (err == -1) {
|
||||
RS_ERR("Call sched_setscheduler error, %s",
|
||||
strerror(errno));
|
||||
}
|
||||
/* #else
|
||||
* RS_INFO("Increase the priority of the process with nice");
|
||||
* err = nice(-20);
|
||||
* if (err == -1) {
|
||||
* RS_ERR("Call nice error, %s", strerror(errno));
|
||||
* }
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* If user specified a initial speed, use that instead of
|
||||
the hardware's default */
|
||||
if (init_speed)
|
||||
u->init_speed = init_speed;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_flags = SA_NOCLDSTOP;
|
||||
sa.sa_handler = sig_alarm;
|
||||
sigaction(SIGALRM, &sa, NULL);
|
||||
|
||||
/* 10 seconds should be enough for initialization */
|
||||
alarm(to);
|
||||
|
||||
n = init_uart(dev, u, send_break, raw);
|
||||
if (n < 0) {
|
||||
RS_ERR("Can't initialize device %d, %s", errno,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
RS_INFO("Device setup complete");
|
||||
|
||||
alarm(0);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_flags = SA_NOCLDSTOP;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
sigaction(SIGPIPE, &sa, NULL);
|
||||
|
||||
sa.sa_handler = sig_term;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
|
||||
sa.sa_handler = sig_hup;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
|
||||
if (detach) {
|
||||
if ((pid = fork())) {
|
||||
if (printpid)
|
||||
RS_INFO("%d", pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
if (i != n)
|
||||
close(i);
|
||||
}
|
||||
|
||||
p.fd = n;
|
||||
p.events = POLLERR | POLLHUP;
|
||||
|
||||
sigfillset(&sigs);
|
||||
sigdelset(&sigs, SIGCHLD);
|
||||
sigdelset(&sigs, SIGPIPE);
|
||||
sigdelset(&sigs, SIGTERM);
|
||||
sigdelset(&sigs, SIGINT);
|
||||
sigdelset(&sigs, SIGHUP);
|
||||
|
||||
while (!__io_canceled) {
|
||||
p.revents = 0;
|
||||
err = ppoll(&p, 1, NULL, &sigs);
|
||||
if (err < 0 && errno == EINTR) {
|
||||
RS_INFO("Got EINTR.");
|
||||
continue;
|
||||
} if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
RS_INFO("err %d, p->revents %04x", err, p.revents);
|
||||
|
||||
/* Restore TTY line discipline */
|
||||
RS_INFO("Restore TTY line discipline");
|
||||
ld = N_TTY;
|
||||
if (ioctl(n, TIOCSETD, &ld) < 0) {
|
||||
RS_ERR("Can't restore line discipline %d, %s", errno,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (p.revents & (POLLERR | POLLHUP)) {
|
||||
RS_INFO("Recover...");
|
||||
reset_bluetooth();
|
||||
goto start;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void util_hexdump(const uint8_t *buf, size_t len)
|
||||
{
|
||||
static const char hexdigits[] = "0123456789abcdef";
|
||||
char str[16 * 3];
|
||||
size_t i;
|
||||
|
||||
if (!buf || !len)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
str[((i % 16) * 3)] = hexdigits[buf[i] >> 4];
|
||||
str[((i % 16) * 3) + 1] = hexdigits[buf[i] & 0xf];
|
||||
str[((i % 16) * 3) + 2] = ' ';
|
||||
if ((i + 1) % 16 == 0) {
|
||||
str[16 * 3 - 1] = '\0';
|
||||
RS_INFO("%s", str);
|
||||
}
|
||||
}
|
||||
|
||||
if (i % 16 > 0) {
|
||||
str[(i % 16) * 3 - 1] = '\0';
|
||||
RS_INFO("%s", str);
|
||||
}
|
||||
}
|
||||
|
||||
int timeout_set(int fd, unsigned int msec)
|
||||
{
|
||||
struct itimerspec itimer;
|
||||
unsigned int sec = msec / 1000;
|
||||
|
||||
memset(&itimer, 0, sizeof(itimer));
|
||||
itimer.it_interval.tv_sec = 0;
|
||||
itimer.it_interval.tv_nsec = 0;
|
||||
itimer.it_value.tv_sec = sec;
|
||||
itimer.it_value.tv_nsec = (msec - (sec * 1000)) * 1000 * 1000;
|
||||
|
||||
return timerfd_settime(fd, 0, &itimer, NULL);
|
||||
}
|
||||
|
||||
188
external/cache/sources/rtk_hciattach/hciattach.h
vendored
Normal file
188
external/cache/sources/rtk_hciattach/hciattach.h
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2003-2009 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
#include <stdint.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define cpu_to_le16(d) (d)
|
||||
#define cpu_to_le32(d) (d)
|
||||
#define le16_to_cpu(d) (d)
|
||||
#define le32_to_cpu(d) (d)
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define cpu_to_le16(d) bswap_16(d)
|
||||
#define cpu_to_le32(d) bswap_32(d)
|
||||
#define le16_to_cpu(d) bswap_16(d)
|
||||
#define le32_to_cpu(d) bswap_32(d)
|
||||
#else
|
||||
#error "Unknown byte order"
|
||||
#endif
|
||||
|
||||
#ifndef N_HCI
|
||||
#define N_HCI 15
|
||||
#endif
|
||||
|
||||
#define HCIUARTSETPROTO _IOW('U', 200, int)
|
||||
#define HCIUARTGETPROTO _IOR('U', 201, int)
|
||||
#define HCIUARTGETDEVICE _IOR('U', 202, int)
|
||||
#define HCIUARTSETFLAGS _IOW('U', 203, int)
|
||||
#define HCIUARTGETFLAGS _IOR('U', 204, int)
|
||||
|
||||
#define HCI_UART_H4 0
|
||||
#define HCI_UART_BCSP 1
|
||||
#define HCI_UART_3WIRE 2
|
||||
#define HCI_UART_H4DS 3
|
||||
#define HCI_UART_LL 4
|
||||
#define HCI_UART_RAW_DEVICE 0
|
||||
|
||||
extern uint8_t DBG_ON;
|
||||
|
||||
/* #define SYSLOG */
|
||||
|
||||
#define LOG_STR "Realtek Bluetooth"
|
||||
#ifdef SYSLOG
|
||||
#define RS_DBG(fmt, arg...) \
|
||||
do{ \
|
||||
if (DBG_ON) \
|
||||
syslog(LOG_DEBUG, "%s :" fmt "\n" , LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_INFO(fmt, arg...) \
|
||||
do{ \
|
||||
syslog(LOG_INFO, "%s :" fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_WARN(fmt, arg...) \
|
||||
do{ \
|
||||
syslog(LOG_WARNING, "%s WARN: " fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_ERR(fmt, arg...) \
|
||||
do{ \
|
||||
syslog(LOG_ERR, "%s ERROR: " fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
#else
|
||||
#define RS_DBG(fmt, arg...) \
|
||||
do{ \
|
||||
if (DBG_ON) \
|
||||
printf("%s :" fmt "\n" , LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_INFO(fmt, arg...) \
|
||||
do{ \
|
||||
printf("%s :" fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_WARN(fmt, arg...) \
|
||||
do{ \
|
||||
printf("%s WARN: " fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_ERR(fmt, arg...) \
|
||||
do{ \
|
||||
printf("%s ERROR: " fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
#endif
|
||||
|
||||
typedef enum _H5_RX_STATE {
|
||||
H5_W4_PKT_DELIMITER,
|
||||
H5_W4_PKT_START,
|
||||
H5_W4_HDR,
|
||||
H5_W4_DATA,
|
||||
H5_W4_CRC
|
||||
} H5_RX_STATE;
|
||||
|
||||
typedef enum _H5_RX_ESC_STATE {
|
||||
H5_ESCSTATE_NOESC,
|
||||
H5_ESCSTATE_ESC
|
||||
} H5_RX_ESC_STATE;
|
||||
|
||||
typedef enum _H5_LINK_STATE {
|
||||
H5_SYNC,
|
||||
H5_CONFIG,
|
||||
H5_INIT,
|
||||
H5_PATCH,
|
||||
H5_HCI_RESET,
|
||||
H5_ACTIVE
|
||||
} H5_LINK_STATE;
|
||||
|
||||
struct patch_info;
|
||||
typedef struct rtb_struct {
|
||||
/* three wire releated */
|
||||
uint8_t rxseq_txack; /* expected rx seq number */
|
||||
uint8_t rxack; /* last packet that the peer ack'ed */
|
||||
uint8_t use_crc;
|
||||
uint8_t is_txack_req; /* txack required */
|
||||
uint8_t msgq_txseq; /* next pkt seq */
|
||||
uint16_t message_crc;
|
||||
uint32_t rx_count; /* expected pkts to recv */
|
||||
|
||||
H5_RX_STATE rx_state;
|
||||
H5_RX_ESC_STATE rx_esc_state;
|
||||
H5_LINK_STATE link_estab_state;
|
||||
|
||||
struct sk_buff *rx_skb;
|
||||
|
||||
uint16_t num_of_cmd_sent;
|
||||
uint16_t lmp_subver;
|
||||
uint16_t hci_rev;
|
||||
uint8_t hci_ver;
|
||||
uint8_t eversion;
|
||||
uint8_t chip_type;
|
||||
|
||||
uint32_t vendor_baud;
|
||||
uint8_t dl_fw_flag;
|
||||
int serial_fd;
|
||||
int uart_flow_ctrl;
|
||||
uint32_t parenb: 16;
|
||||
uint32_t pareven: 16;
|
||||
int final_speed;
|
||||
int total_num; /* total pkt number */
|
||||
int tx_index; /* current sending pkt number */
|
||||
int rx_index; /* ack index from board */
|
||||
int fw_len; /* fw patch file len */
|
||||
int config_len; /* config patch file len */
|
||||
int total_len; /* fw & config extracted buf len */
|
||||
uint8_t *fw_buf; /* fw patch file buf */
|
||||
uint8_t *config_buf; /* config patch file buf */
|
||||
uint8_t *total_buf; /* fw & config extracted buf */
|
||||
#define CMD_STATE_UNKNOWN 0x00
|
||||
#define CMD_STATE_SUCCESS 0x01
|
||||
struct __cmd_state {
|
||||
uint16_t opcode;
|
||||
uint16_t state;
|
||||
} cmd_state;
|
||||
|
||||
struct patch_info *patch_ent;
|
||||
|
||||
int proto;
|
||||
int timerfd;
|
||||
int epollfd;
|
||||
} rtb_struct_t;
|
||||
extern struct rtb_struct rtb_cfg;
|
||||
int timeout_set(int fd, unsigned int msec);
|
||||
int set_speed(int fd, struct termios *ti, int speed);
|
||||
int rtb_init(int fd, int proto, int speed, struct termios *ti);
|
||||
int rtb_post(int fd, int proto, struct termios *ti);
|
||||
void util_hexdump(const uint8_t *buf, size_t len);
|
||||
295
external/cache/sources/rtk_hciattach/hciattach_h4.c
vendored
Normal file
295
external/cache/sources/rtk_hciattach/hciattach_h4.c
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ctype.h>
|
||||
#include <poll.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <sys/epoll.h>
|
||||
#include "hciattach.h"
|
||||
#include "hciattach_h4.h"
|
||||
|
||||
extern struct rtb_struct rtb_cfg;
|
||||
|
||||
static int start_xfer_wait(int fd, uint8_t *cmd, uint16_t len, uint32_t msec,
|
||||
int retry, uint8_t *resp, uint16_t *resp_len)
|
||||
{
|
||||
uint8_t buf[64];
|
||||
int result;
|
||||
int state = 1;
|
||||
int count = 0;
|
||||
int params_len;
|
||||
struct pollfd p[2];
|
||||
uint16_t opcode;
|
||||
|
||||
if (fd == -1 || !cmd || len < 4) {
|
||||
RS_ERR("%s: invalid parameter", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
opcode = ((uint16_t)cmd[2] << 8) + cmd[1];
|
||||
|
||||
start_xfer:
|
||||
result = write(fd, cmd, len);
|
||||
if (result != len) {
|
||||
RS_ERR("%s: Write cmd %04x error, %s", __func__, opcode,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
start_recv:
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(p, 0, sizeof(p));
|
||||
state = 1;
|
||||
count = 0;
|
||||
p[0].fd = fd;
|
||||
p[0].events = POLLERR | POLLHUP | POLLIN;
|
||||
for (;;) {
|
||||
p[0].revents = 0;
|
||||
result = poll(p, 1, msec);
|
||||
if (result < 0) {
|
||||
RS_ERR("Poll call error, %s", strerror(errno));
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
RS_WARN("%s: Timeout", __func__);
|
||||
if (retry <= 0) {
|
||||
RS_ERR("%s: Transfer exhausted", __func__);
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
retry--;
|
||||
goto start_xfer;
|
||||
}
|
||||
|
||||
if (p[0].revents & (POLLERR | POLLHUP)) {
|
||||
RS_ERR("POLLERR or POLLUP happens, %s",
|
||||
strerror(errno));
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (state == 1) {
|
||||
result = read(p[0].fd, buf, 1);
|
||||
if (result == -1 || result != 1) {
|
||||
RS_ERR("%s: Read pkt type error, %s", __func__,
|
||||
strerror(errno));
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
if (result == 1 && buf[0] == 0x04) {
|
||||
count = 1;
|
||||
state = 2;
|
||||
}
|
||||
} else if (state == 2) {
|
||||
result = read(p[0].fd, buf + count, 2);
|
||||
if (result == -1 || result != 2) {
|
||||
RS_ERR("%s: Read pkt header error, %s",
|
||||
__func__, strerror(errno));
|
||||
break;
|
||||
}
|
||||
count += result;
|
||||
state = 3;
|
||||
params_len = buf[2];
|
||||
if (params_len + 3 > sizeof(buf)) {
|
||||
result = -1;
|
||||
RS_ERR("%s: hci event too long", __func__);
|
||||
break;
|
||||
}
|
||||
} else if (state == 3) {
|
||||
result = read(p[0].fd, buf + count, params_len);
|
||||
if (result == -1) {
|
||||
RS_ERR("%s: Read pkt payload error, %s",
|
||||
__func__, strerror(errno));
|
||||
break;
|
||||
}
|
||||
count += result;
|
||||
params_len -= result;
|
||||
if (!params_len)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result >= 0) {
|
||||
if (buf[1] == 0x0e) {
|
||||
uint16_t tmp_opcode;
|
||||
|
||||
tmp_opcode = (uint16_t)buf[4] | buf[5] << 8;
|
||||
if (tmp_opcode == opcode) {
|
||||
RS_INFO("Cmd complete event for cmd %04x",
|
||||
opcode);
|
||||
/* Status is not zero indicating command not
|
||||
* succeeded */
|
||||
if (buf[6])
|
||||
return -1;
|
||||
if (!resp)
|
||||
return 0;
|
||||
if (*resp_len > count)
|
||||
*resp_len = count;
|
||||
memcpy(resp, buf, *resp_len);
|
||||
return 0;
|
||||
} else {
|
||||
RS_WARN("Unexpected cmd complete event, %04x",
|
||||
tmp_opcode);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
RS_INFO("%s: Unexpected hci event packet", __func__);
|
||||
util_hexdump(buf, count);
|
||||
/* Continue receiving */
|
||||
}
|
||||
goto start_recv;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int h4_download_patch(int fd, int index, uint8_t *data, int len)
|
||||
{
|
||||
uint8_t buf[257];
|
||||
uint16_t total_len;
|
||||
int result;
|
||||
uint8_t resp[8];
|
||||
uint16_t rlen = sizeof(resp);
|
||||
|
||||
RS_DBG("fd: %d, index: %d, len: %d", fd, index, len);
|
||||
|
||||
if (data)
|
||||
memcpy(&buf[5], data, len);
|
||||
buf[0] = 0x01;
|
||||
buf[1] = 0x20;
|
||||
buf[2] = 0xfc;
|
||||
buf[3] = len + 1;
|
||||
buf[4] = (uint8_t)index;
|
||||
total_len = len + 5;
|
||||
|
||||
result = start_xfer_wait(fd, buf, total_len, 1000, 0, resp, &rlen);
|
||||
if (result < 0) {
|
||||
RS_ERR("Transfer patch failed, index %d", index);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rlen != 8) {
|
||||
RS_ERR("%s: Unexpected length %u", __func__, rlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return resp[7];
|
||||
}
|
||||
|
||||
int h4_vendor_change_speed(int fd, uint32_t baudrate)
|
||||
{
|
||||
int res;
|
||||
uint8_t cmd[8] = { 0 };
|
||||
|
||||
cmd[0] = 1;
|
||||
cmd[1] = 0x17;
|
||||
cmd[2] = 0xfc;
|
||||
cmd[3] = 4;
|
||||
|
||||
baudrate = cpu_to_le32(baudrate);
|
||||
#ifdef BAUDRATE_4BYTES
|
||||
memcpy((uint16_t *) & cmd[4], &baudrate, 4);
|
||||
#else
|
||||
memcpy((uint16_t *) & cmd[4], &baudrate, 2);
|
||||
cmd[6] = 0;
|
||||
cmd[7] = 0;
|
||||
#endif
|
||||
|
||||
/* TODO: Wait for a while for device to up, just h4 need it */
|
||||
sleep(1);
|
||||
|
||||
RS_DBG("baudrate in change speed command: 0x%02x 0x%02x 0x%02x 0x%02x",
|
||||
cmd[4], cmd[5], cmd[6], cmd[7]);
|
||||
|
||||
res = start_xfer_wait(fd, cmd, 8, 1000, 0, NULL, 0);
|
||||
if (res < 0)
|
||||
RS_ERR("Change Controller baud failed");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int h4_hci_reset(int fd)
|
||||
{
|
||||
int result;
|
||||
uint8_t cmd[4] = { 0x01, 0x03, 0x0c, 0x00};
|
||||
|
||||
RS_INFO("%s: Issue hci reset cmd", __func__);
|
||||
|
||||
result = start_xfer_wait(fd, cmd, sizeof(cmd), 1000, 0, NULL, 0);
|
||||
if (result < 0) {
|
||||
RS_ERR("%s: Failed to send reset cmd", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int h4_read_local_ver(int fd)
|
||||
{
|
||||
uint8_t cmd[4] = { 0x01, 0x01, 0x10, 0x00 };
|
||||
uint8_t resp[16];
|
||||
uint16_t len = sizeof(resp);
|
||||
int result;
|
||||
|
||||
result = start_xfer_wait(fd, cmd, sizeof(cmd), 1000, 0,
|
||||
resp, &len);
|
||||
if (result < 0) {
|
||||
RS_ERR("HCI Read local version info error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len != 15) {
|
||||
RS_ERR("%s: Unexpected length %u", __func__, len);
|
||||
return -1;
|
||||
}
|
||||
rtb_cfg.hci_ver = resp[7];
|
||||
rtb_cfg.hci_rev = (uint32_t)resp[9] << 8 | resp[8];
|
||||
rtb_cfg.lmp_subver = (uint32_t)resp[14] << 8 | resp[13];
|
||||
RS_INFO("hci ver %02x, hci_rev %04x, lmp_subver %04x",
|
||||
rtb_cfg.hci_ver, rtb_cfg.hci_rev, rtb_cfg.lmp_subver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int h4_vendor_read_rom_ver(int fd)
|
||||
{
|
||||
uint8_t cmd[4] = { 0x01, 0x6d, 0xfc, 0x00 };
|
||||
uint8_t resp[16];
|
||||
uint16_t len = sizeof(resp);
|
||||
int result;
|
||||
|
||||
result = start_xfer_wait(fd, cmd, sizeof(cmd), 1000, 0,
|
||||
resp, &len);
|
||||
if (result < 0) {
|
||||
RS_ERR("HCI Read local version info error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len != 8) {
|
||||
RS_ERR("%s: Unexpected length %u", __func__, len);
|
||||
return -1;
|
||||
}
|
||||
rtb_cfg.eversion = resp[7];
|
||||
RS_INFO("eversion %02x", rtb_cfg.eversion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
7
external/cache/sources/rtk_hciattach/hciattach_h4.h
vendored
Normal file
7
external/cache/sources/rtk_hciattach/hciattach_h4.h
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <stdint.h>
|
||||
int h4_download_patch(int fd, int index, uint8_t *data, int len);
|
||||
int h4_vendor_change_speed(int fd, uint32_t baudrate);
|
||||
int h4_hci_reset(int fd);
|
||||
int h4_read_local_ver(int fd);
|
||||
int h4_vendor_read_rom_ver(int fd);
|
||||
2024
external/cache/sources/rtk_hciattach/hciattach_rtk.c
vendored
Normal file
2024
external/cache/sources/rtk_hciattach/hciattach_rtk.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1233
external/cache/sources/rtk_hciattach/rtb_fwc.c
vendored
Normal file
1233
external/cache/sources/rtk_hciattach/rtb_fwc.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
75
external/cache/sources/rtk_hciattach/rtb_fwc.h
vendored
Normal file
75
external/cache/sources/rtk_hciattach/rtb_fwc.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Realtek Semiconductor Corporation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
struct rtb_struct;
|
||||
|
||||
#define BAUDRATE_4BYTES
|
||||
|
||||
#define ROM_LMP_NONE 0x0000
|
||||
#define ROM_LMP_8723a 0x1200
|
||||
#define ROM_LMP_8723b 0x8723
|
||||
#define ROM_LMP_8821a 0x8821
|
||||
#define ROM_LMP_8761a 0x8761
|
||||
#define ROM_LMP_8761btc 0x8763
|
||||
|
||||
#define ROM_LMP_8703a 0x87b3
|
||||
#define ROM_LMP_8763a 0x8763
|
||||
#define ROM_LMP_8703b 0x8703
|
||||
#define ROM_LMP_8723c 0x87c3 /* ??????? */
|
||||
#define ROM_LMP_8822b 0x8822
|
||||
#define ROM_LMP_8822c 0x8822
|
||||
#define ROM_LMP_8723cs_xx 0x8704
|
||||
#define ROM_LMP_8723cs_cg 0x8705
|
||||
#define ROM_LMP_8723cs_vf 0x8706
|
||||
|
||||
/* Chip type */
|
||||
#define CHIP_8703AS 1
|
||||
#define CHIP_8723CS_CG 3
|
||||
#define CHIP_8723CS_VF 4
|
||||
#define CHIP_8723CS_XX 5
|
||||
#define CHIP_8703BS 7
|
||||
|
||||
/* software id */
|
||||
#define CHIP_UNKNOWN 0x00
|
||||
#define CHIP_8761AT 0x1F
|
||||
#define CHIP_8761ATF 0x2F
|
||||
#define CHIP_8761BTC 0x3F
|
||||
#define CHIP_8761BH4 0x4F
|
||||
#define CHIP_8723BS 0x5F
|
||||
#define CHIP_BEFORE 0x6F
|
||||
#define CHIP_8822BS 0x70
|
||||
#define CHIP_8723DS 0x71
|
||||
#define CHIP_8821CS 0x72
|
||||
#define CHIP_8822CS 0x73
|
||||
#define CHIP_8761B 0x74
|
||||
|
||||
#define RTL_FW_MATCH_CHIP_TYPE (1 << 0)
|
||||
#define RTL_FW_MATCH_HCI_VER (1 << 1)
|
||||
#define RTL_FW_MATCH_HCI_REV (1 << 2)
|
||||
struct patch_info {
|
||||
uint32_t match_flags;
|
||||
uint8_t chip_type;
|
||||
uint16_t lmp_subver;
|
||||
uint16_t proj_id;
|
||||
uint8_t hci_ver;
|
||||
uint16_t hci_rev;
|
||||
char *patch_file;
|
||||
char *config_file;
|
||||
char *ic_name;
|
||||
};
|
||||
|
||||
struct patch_info *get_patch_entry(struct rtb_struct *btrtl);
|
||||
uint8_t *rtb_read_config(struct rtb_struct *btrtl, int *cfg_len);
|
||||
uint8_t *rtb_read_firmware(struct rtb_struct *btrtl, int *fw_len);
|
||||
uint8_t *rtb_get_final_patch(int fd, int proto, int *rlen);
|
||||
Reference in New Issue
Block a user