From: Taejin Woo Date: Wed, 23 Oct 2013 05:01:40 +0000 (+0900) Subject: Merge the latest firmware code in Tizen_2.2 RSA X-Git-Tag: 2.2.1_release X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen_2.2;p=adaptation%2Fdevices%2Fbluetooth-firmware-bcm.git Merge the latest firmware code in Tizen_2.2 RSA We do firmware Code Sync in tizen_2.2 RSA. Change-Id: Iff5efd6c9625bb9aed33da34bfc20c37790f613a --- diff --git a/CMakeLists.txt b/CMakeLists.txt index cabe6eb..94e9747 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,5 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -INCLUDE(FindPkgConfig) -pkg_check_modules(package REQUIRED glib-2.0 tapi) - FOREACH(flag ${package_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) diff --git a/packaging/bluetooth-firmware-bcm.spec b/packaging/bluetooth-firmware-bcm.spec index 257ab1d..67cb8d3 100644 --- a/packaging/bluetooth-firmware-bcm.spec +++ b/packaging/bluetooth-firmware-bcm.spec @@ -9,7 +9,6 @@ License: Apache Source0: bluetooth-firmware-bcm-%{version}.tar.gz BuildRequires: cmake -BuildRequires: pkgconfig(tapi) %description firmware and tools for bluetooth diff --git a/scripts/bt-dev-start-c210.sh b/scripts/bt-dev-start-c210.sh index 386fd24..1be1b62 100755 --- a/scripts/bt-dev-start-c210.sh +++ b/scripts/bt-dev-start-c210.sh @@ -4,6 +4,7 @@ BT_UART_DEVICE=/dev/ttySAC0 BT_CHIP_TYPE=bcm2035 BCM_TOOL=/usr/bin/bcmtool_4330b1 +BT_ADDR=/csa/bluetooth/.bd_addr BT_PLATFORM_DEFAULT_HCI_NAME="TIZEN-Mobile" UART_SPEED=3000000 @@ -22,10 +23,13 @@ then mknod $BT_UART_DEVICE c 204 64 fi -if [ ! -e /csa/bluetooth/.bd_addr ] +# Set BT address: This will internally check for the file presence +/usr/bin/setbd + +#if the setbd return non 0, which means incorrect bd address file, then exit +if [ $? -ne 0 ] then - # Set BT address - /usr/bin/setbd + exit 1 fi # Trun-on Bluetooth Chip @@ -39,14 +43,38 @@ else echo "Bluetooth device is DOWN" echo "Registering Bluetooth device" - $BCM_TOOL $BT_UART_DEVICE -FILE=/usr/etc/bluetooth/$BCM_FIRMWARE -BAUD=$UART_SPEED -ADDR=/csa/bluetooth/.bd_addr -SETSCO=0,0,0,0,0,0,0,3,3,0 -LP > /dev/null 2>&1 + $BCM_TOOL $BT_UART_DEVICE -FILE=/usr/etc/bluetooth/$BCM_FIRMWARE -BAUD=$UART_SPEED -ADDR=$BT_ADDR -SETSCO=0,0,0,0,0,0,0,3,3,0 -LP > /dev/null 2>&1 & + bcmtool_pid=$! + #Check next 2.4 seconds for bcmtool success + for (( i=1; i<=24; i++)) + do + sleep 0.1 + kill -0 $bcmtool_pid + bcmtool_alive=$? + + if [ $i -eq 24 ] + then + echo "time expired happen $i" + kill -TERM $bcmtool_pid + rfkill block bluetooth + exit 1 + fi + + if [ $bcmtool_alive -eq 0 ] + then + echo "Continue....$i" + continue + else + echo "Break.......$i" + break + fi + done # Attaching Broadcom device if (/usr/sbin/hciattach $BT_UART_DEVICE -s $UART_SPEED $BT_CHIP_TYPE $UART_SPEED flow); then sleep 0.1 - /usr/sbin/hciconfig hci0 up - /usr/sbin/hciconfig hci0 name $BT_PLATFORM_DEFAULT_HCI_NAME - /usr/sbin/hciconfig hci0 sspmode 1 + /usr/sbin/hciconfig hci0 name $BT_PLATFORM_DEFAULT_HCI_NAME + /usr/sbin/hciconfig hci0 sspmode 1 echo "HCIATTACH success" else echo "HCIATTACH failed" diff --git a/scripts/bt-dev-start-e4412.sh b/scripts/bt-dev-start-e4412.sh index 51c2945..3a9e663 100755 --- a/scripts/bt-dev-start-e4412.sh +++ b/scripts/bt-dev-start-e4412.sh @@ -1,10 +1,14 @@ #!/bin/sh +# # Script for registering Broadcom UART BT device +# BT_UART_DEVICE=/dev/ttySAC0 BT_CHIP_TYPE=bcm2035 BCM_TOOL=/usr/bin/bcmtool_4330b1 +BT_ADDR=/csa/bluetooth/.bd_addr + BT_PLATFORM_DEFAULT_HCI_NAME="TIZEN-Mobile" UART_SPEED=3000000 @@ -12,12 +16,11 @@ UART_SPEED=3000000 # SEMCO external LNA, I2S slave BCM_FIRMWARE=BCM4334B0_002.001.013.0079.0081.hcd +HOST_NAME=`grep Hardware /proc/cpuinfo | awk "{print \\$3}"` REVISION_NUM=`grep Revision /proc/cpuinfo | awk "{print \\$3}"` REVISION_HIGH=`echo $REVISION_NUM| cut -c1-2` REVISION_LOW=`echo $REVISION_NUM| cut -c3-` -#HARDWARE=`grep Hardware /proc/cpuinfo | awk "{print \\$3}"` - echo $BCM_FIRMWARE if [ ! -e "$BT_UART_DEVICE" ] @@ -25,10 +28,13 @@ then mknod $BT_UART_DEVICE c 204 64 fi -if [ ! -e /csa/bluetooth/.bd_addr ] +# Set BT address: This will internally check for the file presence +/usr/bin/setbd + +#if the setbd return non 0, which means incorrect bd address file, then exit +if [ $? -ne 0 ] then - # Set BT address - /usr/bin/setbd + exit 1 fi rfkill unblock bluetooth @@ -41,18 +47,44 @@ else echo "Bluetooth device is DOWN" echo "Registering Bluetooth device" - $BCM_TOOL $BT_UART_DEVICE -FILE=/usr/etc/bluetooth/$BCM_FIRMWARE -BAUD=$UART_SPEED -ADDR=/csa/bluetooth/.bd_addr -SETSCO=0,0,0,0,0,0,0,3,3,0 -LP > /dev/null 2>&1 + $BCM_TOOL $BT_UART_DEVICE -FILE=/usr/etc/bluetooth/$BCM_FIRMWARE -BAUD=$UART_SPEED -ADDR=$BT_ADDR -SETSCO=0,0,0,0,0,0,0,3,3,0 -LP > /dev/null 2>&1 & + bcmtool_pid=$! + #Check next 5 seconds for bcmtool success + for (( i=1; i<=50; i++)) + do + sleep 0.1 + kill -0 $bcmtool_pid + bcmtool_alive=$? + + if [ $i -eq 50 ] + then + echo "time expired happen $i" + kill -TERM $bcmtool_pid + rfkill block bluetooth + cp /var/log/messages /var/lib/bluetooth/ + exit 1 + fi + + if [ $bcmtool_alive -eq 0 ] + then + echo "Continue....$i" + continue + else + echo "Break.......$i" + break + fi + done # Attaching Broadcom device if (/usr/sbin/hciattach $BT_UART_DEVICE -s $UART_SPEED $BT_CHIP_TYPE $UART_SPEED flow); then sleep 0.1 - /usr/sbin/hciconfig hci0 up /usr/sbin/hciconfig hci0 name $BT_PLATFORM_DEFAULT_HCI_NAME /usr/sbin/hciconfig hci0 sspmode 1 echo "HCIATTACH success" else echo "HCIATTACH failed" rfkill block bluetooth + cp /var/log/messages /var/lib/bluetooth/ fi fi diff --git a/scripts/bt-set-addr.sh b/scripts/bt-set-addr.sh index 8fcb3f2..a2624a0 100755 --- a/scripts/bt-set-addr.sh +++ b/scripts/bt-set-addr.sh @@ -4,11 +4,11 @@ # Script for setting Bluetooth Address # -if [ -e /csa/bluetooth/.bd_addr ] -then - echo "Already .bd_addr exists" - exit 0 -fi +#if [ -e /csa/bluetooth/.bd_addr ] +#then +# echo "Already .bd_addr exists" +# exit 0 +#fi /usr/bin/setbd diff --git a/set-address/CMakeLists.txt b/set-address/CMakeLists.txt index 2ff386b..c3e04db 100644 --- a/set-address/CMakeLists.txt +++ b/set-address/CMakeLists.txt @@ -13,9 +13,6 @@ IF("${ARCH}" STREQUAL "arm") ENDIF("${ARCH}" STREQUAL "arm") ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") -ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"") -ADD_DEFINITIONS("-D__BROADCOM_PATCH__") -ADD_DEFINITIONS("-DDEBUG_EN") ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${package_LDFLAGS}) diff --git a/set-address/setbd.c b/set-address/setbd.c index f9543e4..fbcfff1 100644 --- a/set-address/setbd.c +++ b/set-address/setbd.c @@ -24,99 +24,32 @@ #include #include #include -#include +#include #include -#include -#include - -#ifdef __TI_PATCH__ -#define BT_CHIP_TI -#else -#ifdef __BROADCOM_PATCH__ -#define BT_CHIP_BROADCOM -#else -#define BT_CHIP_CSR -#endif -#endif - -#ifdef DEBUG_EN -#define APP_DBG(format, args...) printf("%s(), line[%d]: " format, __FUNCTION__, __LINE__, ##args) -#define APP_DEBUG(format, args...) printf(format, ##args) -#else -#define APP_DBG(format, args...) -#define APP_DEBUG(format, args...) -#endif +#include #define BD_ADDR_PATH "/csa/bluetooth" #define BD_ADDR_FILE "/csa/bluetooth/.bd_addr" -#define PSKEY_TEMP_FILE "/csa/bluetooth/.bluetooth.psr" -#define PSR_FILE "/csa/bluetooth/bluetooth.psr" #define BD_ADDR_LEN 14 #define BD_PREFIX "0002\n" -#define PSKEY_LEN 27 -#define PSKEY_BDADDR_PREFIX "&0001 = 0012 " - -#define READ_BD_FILE_MAX 300 - -static int success_make_bt_address_from_imei = -1; -static GMainLoop *loop; -const char *DEFAULT_IMEI = "004999010640000"; - -#if defined(BT_CHIP_CSR) || defined(BT_CHIP_BROADCOM) -int addremoveBD(char *path, char *pskey) -{ - FILE *fd, *new; - int ret; - char cmp[READ_BD_FILE_MAX]; - char *result; - - fd = fopen(path, "r"); - if (NULL == fd) { - APP_DBG("Error open psr file\r\n"); - return -21; - } - - new = fopen(PSKEY_TEMP_FILE, "w"); - if (NULL == new) { - APP_DBG("Error creat temp file\r\n"); - fclose(fd); - return -22; - } - - ret = fputs(pskey, new); - - while (1) { - result = fgets(cmp, READ_BD_FILE_MAX, fd); - - APP_DBG("PSR : [%s]\r\n", cmp); - - if ((NULL != result) && (0 == strncmp(cmp, "&0001", 5))) { - APP_DBG("Find BD address set script\r\n"); - continue; - } - - if (NULL == result) { - APP_DBG("EOF reaches\r\n"); - fclose(fd); - fclose(new); - return 1; - } - - ret = fputs(cmp, new); - } - - return 0; -} - void makeRandomBD(unsigned char *buf) { int ran; int i; unsigned int seed; + struct timeval tv; + memcpy(buf, BD_PREFIX, 5); - seed = time(NULL); + i = gettimeofday(&tv, NULL); + + if (i < 0) { + perror("Fail to call gettimeofday()"); + seed = time(NULL); + } else + seed = (unsigned int)tv.tv_usec; + for (i = 5; i < BD_ADDR_LEN; i++) { if (7 == i) { buf[i] = '\n'; @@ -129,131 +62,11 @@ void makeRandomBD(unsigned char *buf) ran += 0x57; buf[i] = ran; } - APP_DEBUG("Random number is\r\n"); + printf("Random number is\r\n"); for (i = 0; i < BD_ADDR_LEN; i++) { - APP_DEBUG("%c", buf[i]); - } - APP_DEBUG("\r\n"); -} -#endif - -#ifdef BT_CHIP_TI -int readBDaddrTI(void) -{ - int i, cnt_lap = 0, cnt_uap = 0, cnt_nap = 0; - int dev_id, fd, filedesc; - BD_ADDR_T bdaddr; - char address[18]; - char nap[4], uap[2], lap[6]; - int ret = 0; - dev_id = hci_get_route(NULL); - if (dev_id < 0) { - APP_DBG("Bluetooth device not available!!!\r\n"); - return -1; - } - fd = hci_open_dev(dev_id); - if (fd < 0) { - APP_DBG("HCI open fail!!!\r\n"); - return -2; - } - - if (0 > hci_read_bd_addr(fd, &bdaddr, 1000)) { - APP_DBG("Read BD ADDR failed!!!\r\n"); - return -3; - } - hci_close_dev(fd); - - ba2str(&bdaddr, address); - for (i = 0; i < 17; i++) { - if (':' == address[i]) - continue; - - if (5 > i) - nap[cnt_nap++] = address[i]; - else if (8 > i) - uap[cnt_uap++] = address[i]; - else - lap[cnt_lap++] = address[i]; - } - - APP_DBG("BT address [%s], nap[%c%c%c%c], uap[%c%c], lap[%c%c%c%c%c%c]\r\n", - address, nap[0], nap[1], nap[2], nap[3], uap[0], uap[1], lap[0], - lap[1], lap[2], lap[3], lap[4], lap[5]); - - filedesc = open(BD_ADDR_FILE, - O_RDWR | O_CREAT | O_TRUNC | O_SYNC, 0644); - if (0 > filedesc) { - APP_DBG("File creation fail!!!\r\n"); - return -4; - } - ret = write(filedesc, nap, 4); - ret = write(filedesc, "\n", 1); - ret = write(filedesc, uap, 2); - ret = write(filedesc, "\n", 1); - ret = write(filedesc, lap, 6); - ret = write(filedesc, "\n", 1); - close(filedesc); - - return 0; -} -#endif -int make_bt_address_from_tapi_imei(unsigned char *bt_address) -{ - int i = 0; - TapiHandle *handler; - char *imei_no; - - if (bt_address == NULL) - return -EBADR; - - handler = tel_init(NULL); - if (!handler) { - APP_DEBUG("Telephony initilization failed\n"); - return -ENODATA; - } - - imei_no = tel_get_misc_me_imei_sync(handler); - tel_deinit(handler); - if (!imei_no) { - APP_DEBUG("Telephony IMEI getting failed \n"); - return -ENODATA; + printf("%c", buf[i]); } - - if (strlen(imei_no) < BD_ADDR_LEN) { - free(imei_no); - APP_DEBUG("TAPI_IMEI Reading Error\n"); - return -ENODATA; - } - - APP_DEBUG("TAPI_IMEI: %s\n", imei_no); - - if (strcmp(imei_no, DEFAULT_IMEI) == 0) { - APP_DEBUG("TAPI_IMEI is defulat IMEI\n"); - free(imei_no); - return -ENODATA; - } - - memcpy(bt_address, BD_PREFIX, 5); - - for (i = 5; i < BD_ADDR_LEN; i++) { - if (i == 7) { - bt_address[i] = '\n'; - continue; - } - - bt_address[i] = imei_no[i]; - } - - free(imei_no); - - APP_DEBUG("Bluetooth Address\n"); - for (i = 0; i < BD_ADDR_LEN; i++) - APP_DEBUG("%c", bt_address[i]); - - APP_DEBUG("\n"); - - return 0; - + printf("\r\n"); } void make_bt_address_folder(void) @@ -265,7 +78,7 @@ void make_bt_address_folder(void) if (dp == NULL) { if (mkdir(BD_ADDR_PATH, 0755) < 0) { err = -errno; - APP_DEBUG("mkdir: %s(%d)", strerror(-err), -err); + printf("mkdir: %s(%d)", strerror(-err), -err); } return; } @@ -273,119 +86,101 @@ void make_bt_address_folder(void) closedir(dp); } -int make_bt_address(gboolean overwrite_bt_address) +int make_bt_address(void) { -#if defined(BT_CHIP_CSR) || defined(BT_CHIP_BROADCOM) - int fd; - int i; unsigned char txt[BD_ADDR_LEN]; - unsigned char nap[4 + 1], uap[2 + 1], lap[6 + 1]; - char pskey[PSKEY_LEN + 3]; + char nap[4 + 1], uap[2 + 1], lap[6 + 1]; int ret; make_bt_address_folder(); fd = open(BD_ADDR_FILE, O_RDONLY | O_SYNC); - if (fd < 0 || overwrite_bt_address == TRUE) { - if (fd < 0) - APP_DEBUG("File not exist\n"); - else - close(fd); - - if (overwrite_bt_address) { - APP_DEBUG("Overwrite BT address because TAPI write correct IMEI.\n"); - } + if (fd < 0) { + printf("File not exist\n"); fd = open(BD_ADDR_FILE, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, 0644); if (fd < 0) { - APP_DEBUG("Can't open address file\n"); - return 0; + printf("Can't open address file\n"); + return -1; } - success_make_bt_address_from_imei = - make_bt_address_from_tapi_imei(txt); - if (success_make_bt_address_from_imei < 0) - makeRandomBD(txt); + makeRandomBD(txt); ret = write(fd, txt, BD_ADDR_LEN); + if (ret != BD_ADDR_LEN) { + printf("Unable to write device address\n"); + close(fd); + unlink(BD_ADDR_FILE); + return -1; + } + lseek(fd, 0, SEEK_SET); } else { - APP_DEBUG("%s is already existed\n", BD_ADDR_FILE); - success_make_bt_address_from_imei = 0; + printf("%s is already existed\n", BD_ADDR_FILE); } ret = read(fd, nap, 5); - ret = read(fd, uap, 3); - ret = read(fd, lap, 7); - close(fd); + if (ret != 5) + goto err; -#if defined(BT_CHIP_CSR) - APP_DEBUG("nap["); - for (i = 0; i < 4; i++) - APP_DEBUG("%c", nap[i]); - APP_DEBUG("]\r\n"); + ret = read(fd, uap, 3); + if (ret != 3) + goto err; - APP_DEBUG("uap["); - for (i = 0; i < 2; i++) - APP_DEBUG("%c", uap[i]); - APP_DEBUG("]\r\n"); + ret = read(fd, lap, 7); + if (ret != 6) + goto err; - APP_DEBUG("lap["); - for (i = 0; i < 6; i++) - APP_DEBUG("%c", lap[i]); - APP_DEBUG("]\r\n"); + close(fd); - sprintf(pskey, "&0001 = 0012 %c%c%c%c %c%c%c%c %c%c%c%c\r\n", - lap[0], lap[1], lap[2], lap[3], lap[4], lap[5], - uap[0], uap[1], nap[0], nap[1], nap[2], nap[3]); + /* Unfortunately 00023fbf0a1a address is duplicated from the + * previous IMEI logic. So this address should be updated with + * random value. + * + * This is temporal code. And this would be reverted around a few week + * after the wrong addressed device has proper address. + */ + if (strncmp(nap, "0002", 4) == 0 && + strncmp(uap, "3f", 2) == 0 && strncmp(lap, "bf0a1a", 6) == 0) { + printf("%s has wrong address\n", BD_ADDR_FILE); + fd = open(BD_ADDR_FILE, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, + 0644); - APP_DEBUG("BD PSKEY ["); - for (i = 0; i < PSKEY_LEN; i++) - APP_DEBUG("%c", pskey[i]); - APP_DEBUG("]\r\n"); + if (fd < 0) { + printf("Can't open address file\n"); + return -1; + } - ret = addremoveBD(PSR_FILE, pskey); -#endif - return ret; -#elif defined(BT_CHIP_TI) - int fd; - int ret; + makeRandomBD(txt); + ret = write(fd, txt, BD_ADDR_LEN); + if (ret != BD_ADDR_LEN) { + printf("Unable to write device address\n"); + close(fd); + unlink(BD_ADDR_FILE); + return -1; + } - fd = open(BD_ADDR_FILE, O_RDONLY, 0644); - if (0 > fd) { - APP_DBG("File not exists\r\n"); - ret = readBDaddrTI(); - } else { - APP_DBG("File exists\r\n"); + lseek(fd, 0, SEEK_SET); close(fd); - ret = 0; } return ret; -#else - printf("error BT CHIP not defined!!!\n"); - return 0; -#endif -} - -gboolean exit_cb(gpointer data) -{ - - APP_DEBUG("Time out!!!\n"); - g_main_loop_quit(loop); - - return FALSE; + err: + printf("read() failed, ret = %d\n", ret); + close(fd); + unlink(BD_ADDR_FILE); + return -1; } int main() { - loop = g_main_loop_new(NULL, FALSE); - APP_DEBUG("Bluetooth Address Setting\n"); - make_bt_address(FALSE); + printf("Bluetooth Address Setting\n"); + if (make_bt_address() < 0) + return -1; return 0; } diff --git a/tools/bcmtool_4330b1.c b/tools/bcmtool_4330b1.c index 7fac3f7..6917634 100644 --- a/tools/bcmtool_4330b1.c +++ b/tools/bcmtool_4330b1.c @@ -61,27 +61,35 @@ /* Local Feature */ #define BCM_DISABLE_RF_PWRCTRL FALSE - - - #define RELEASE_DATE "2011.02.07" #define DEBUG 1 -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef unsigned long UINT32; -typedef signed long INT32; -typedef signed char INT8; -typedef signed short INT16; -typedef unsigned char BOOLEAN; +/* Broadcom AXI patch for BCM4335 chipset only */ +#define DEPLOY_4335A_AXI_BRIDGE_PATCH TRUE -#define FALSE 0 -#define TRUE (!FALSE) +/* The fix for AXI bridge contention between BT and WLAN: + * + * Set this TRUE only when + * 1. the platform is using BCM4335A or BCM4335B0, and + * 2. Kernel source has implemented AXI BRIDGE lock logic. + */ +#ifndef DEPLOY_4335A_AXI_BRIDGE_PATCH +#define DEPLOY_4335A_AXI_BRIDGE_PATCH FALSE +#endif -#define BD_ADDR_LEN 6 /* Device address length */ -typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */ +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned long UINT32; +typedef signed long INT32; +typedef signed char INT8; +typedef signed short INT16; +typedef unsigned char BOOLEAN; +#define FALSE 0 +#define TRUE (!FALSE) +#define BD_ADDR_LEN 6 /* Device address length */ +typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */ #define HCI_GRP_LINK_CONTROL_CMDS (0x01 << 10) #define HCI_GRP_LINK_POLICY_CMDS (0x02 << 10) @@ -93,9 +101,9 @@ typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */ #define HCI_GRP_L2CAP_HCI_EVTS (0x08 << 10) #define HCI_GRP_VENDOR_SPECIFIC (0x3F << 10) - #define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) #define HCI_SET_EVENT_FILTER (0x0005 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) +#define HCI_READ_LOCAL_NAME (0x0014 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) #define HCI_READ_SCAN_ENABLE (0x0019 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) #define HCI_WRITE_SCAN_ENABLE (0x001A | HCI_GRP_HOST_CONT_BASEBAND_CMDS) @@ -113,7 +121,8 @@ typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */ #define HCI_BRCM_WRITE_SLEEP_MODE (0x0027 | HCI_GRP_VENDOR_SPECIFIC) #define HCI_BRCM_DOWNLOAD_MINI_DRV (0x002E | HCI_GRP_VENDOR_SPECIFIC) #define VSC_WRITE_UART_CLOCK_SETTING (0x0045 | HCI_GRP_VENDOR_SPECIFIC) - +#define HCI_VSC_WRITE_RAM (0x004C | HCI_GRP_VENDOR_SPECIFIC) +#define HCI_VSC_LAUNCH_RAM (0x004E | HCI_GRP_VENDOR_SPECIFIC) #define VOICE_SETTING_MU_LAW_MD 0x0100 #define VOICE_SETTING_LINEAR_MD 0x0060 @@ -147,7 +156,6 @@ typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */ #define DEBUG5(m,n1,n2,n3,n4,n5) if(debug_mode) {fprintf(stderr,m,n1,n2,n3,n4,n5);} #define DEBUG6(m,n1,n2,n3,n4,n5,n6) if(debug_mode) {fprintf(stderr,m,n1,n2,n3,n4,n5,n6);} - #define STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;} #define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;} #define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;} @@ -161,10 +169,10 @@ typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */ p1[3] = p2[2]; \ p1[4] = p2[1]; \ p1[5] = p2[0]; \ - } while (0) + } while (0) +UINT8 vsc_for_pcm_config[5] = { 0x00, 0x00, 0x03, 0x03, 0x00 }; -UINT8 vsc_for_pcm_config[5] = {0x00, 0x00, 0x03, 0x03, 0x00}; /* Byte1 -- 0 for MSb first Byte2 -- 0 Fill value @@ -173,7 +181,8 @@ UINT8 vsc_for_pcm_config[5] = {0x00, 0x00, 0x03, 0x03, 0x00}; Byte5 -- 1 Right justified (0 for left justified) */ -UINT8 vsc_for_sco_pcm[5] = {0x00, 0x01, 0x00, 0x01, 0x01}; +UINT8 vsc_for_sco_pcm[5] = { 0x00, 0x01, 0x00, 0x01, 0x01 }; + /* Neverland : PCM, 256, short, master ,master Volance : PCM, 256, short, master ,master @@ -183,11 +192,13 @@ UINT8 vsc_for_sco_pcm[5] = {0x00, 0x01, 0x00, 0x01, 0x01}; Byte3 -- 0 for short frame sync 1 for long frame sync Byte4 -- 0 Clock direction 0 for same as sync 1 for opposite direction Byte5 -- 0 for slave 1 for master -*/ +*/ + +int fd; /* HCI handle */ -int fd; /* HCI handle */ +BOOLEAN debug_mode = FALSE; /* Debug Mode Enable */ -BOOLEAN debug_mode = FALSE; /* Debug Mode Enable */ +BOOLEAN use_two_stop_bits = FALSE; /* Flag of two stop bits for tty */ unsigned char buffer[1024]; @@ -195,332 +206,461 @@ struct termios termios; void ChangeBaudRate(UINT32 baudrate); - void exit_err(UINT8 err) { #if ( HIGH_SPEED_PATCHRAM_DOWNLOAD == TRUE ) - ChangeBaudRate(115200); + ChangeBaudRate(115200); #endif - exit(err); + exit(err); } void print_time(void) { #if 0 - struct timespec tp; - int rs; + struct timespec tp; + int rs; - rs = clock_gettime(CLOCK_REALTIME,&tp); - fprintf(stderr, "[%04d : %06d]\n", tp.tv_sec, tp.tv_nsec/1000); - return; + rs = clock_gettime(CLOCK_REALTIME, &tp); + fprintf(stderr, "[%04d : %06d]\n", tp.tv_sec, tp.tv_nsec / 1000); + return; #endif } void dump(unsigned char *out, int len) { - int i; - - for (i = 0; i < len; i++) - { - if (!(i % 16)) - { - DEBUG0( "\n"); - } - DEBUG1( "%02x ", out[i]); - } - DEBUG0( "\n\n"); + int i; + + for (i = 0; i < len; i++) { + if (!(i % 16)) { + DEBUG0("\n"); + } + DEBUG1("%02x ", out[i]); + } + DEBUG0("\n\n"); } -UINT8 SendCommand(UINT16 opcode, UINT8 param_len, UINT8 *p_param_buf) +UINT8 SendCommand(UINT16 opcode, UINT8 param_len, UINT8 * p_param_buf) { - UINT8 pbuf[255] = {0,}; - UINT8 i=0; - - pbuf[0] = 0x1; - pbuf[1] = (UINT8)(opcode); - pbuf[2] = (UINT8)(opcode >>8); - pbuf[3] = param_len; - - for (i=0; i> 8); + pbuf[3] = param_len; - DEBUG1( "Send %d",param_len+4); + for (i = 0; i < param_len; i++) { + pbuf[i + 4] = *p_param_buf++; + } - dump(pbuf, param_len+4); + DEBUG1("Send %d", param_len + 4); - write(fd, pbuf, param_len+4); - return 0; + dump(pbuf, param_len + 4); + + write(fd, pbuf, param_len + 4); + return 0; } void expired(int sig) { - static UINT8 count = 0; - DEBUG0( "expired try again\n"); - SendCommand(HCI_RESET, 0, NULL); - alarm(1); - count++; - - if(count > 3) - { - fprintf(stderr, "[ERR] HCI reset time expired\n"); - exit(1); - } + static UINT8 count = 0; + DEBUG0("expired try again\n"); + SendCommand(HCI_RESET, 0, NULL); + alarm(1); + count++; + + if (count > 3) { + fprintf(stderr, "[ERR] HCI reset time expired\n"); + exit(1); + } } void read_event(int fd, unsigned char *buffer) { - int i = 0; - int len = 3; - int count; + int i = 0; + int len = 3; + int count; - while ((count = read(fd, &buffer[i], len)) < len) - { - i += count; - len -= count; - } + while ((count = read(fd, &buffer[i], len)) < len) { + i += count; + len -= count; + } - i += count; - len = buffer[2]; + i += count; + len = buffer[2]; - while ((count = read(fd, &buffer[i], len)) < len) - { - i += count; - len -= count; - } + while ((count = read(fd, &buffer[i], len)) < len) { + i += count; + len -= count; + } #ifdef DEBUG - count += i; + count += i; - DEBUG1( "\nreceived %d", count); - dump(buffer, count); + DEBUG1("\nreceived %d", count); + dump(buffer, count); #endif } -INT32 filesize (char *name) +INT32 filesize(char *name) { - INT32 size; - int flag; - struct stat buf; + INT32 size; + int flag; + struct stat buf; - flag = stat (name,&buf); - if (flag == -1) - return -1; + flag = stat(name, &buf); + if (flag == -1) + return -1; - size = buf.st_size; - return (size); + size = buf.st_size; + return (size); } void DisplayProgress(int total, int val) { #if 0 - #define PROGRESS_NUM 20 - - int p; - int i; - char text[PROGRESS_NUM+2]={0,}; - - text[0]='['; - text[PROGRESS_NUM+1]=']'; - p=(val*PROGRESS_NUM)/total; - - for ( i=1; i<=p; i++) +#define PROGRESS_NUM 20 + + int p; + int i; + char text[PROGRESS_NUM + 2] = { 0, }; + + text[0] = '['; + text[PROGRESS_NUM + 1] = ']'; + p = (val * PROGRESS_NUM) / total; + + for (i = 1; i <= p; i++) { + text[i] = '='; + } + + for (i = p + 1; i <= PROGRESS_NUM; i++) { + text[i] = ' '; + } + + for (i = 0; i <= (PROGRESS_NUM + 1); i++) { + fprintf(stderr, "%c", text[i]); + } + + if (p >= PROGRESS_NUM) + fprintf(stderr, " %6d/%6d\n", val, total); + else + fprintf(stderr, " %6d/%6d\r", val, total); +#else + if (val == total) + fprintf(stderr, " %6d/%6d\n", val, total); + else + fprintf(stderr, " %6d/%6d\r", val, total); +#endif +} + +#if (DEPLOY_4335A_AXI_BRIDGE_PATCH == TRUE) +/* 4335A/B0 AXI BRIDEG lock cookie */ +struct btlock { + int lock; + int cookie; +}; + +#define AXI_LOCK_COOKIE ('B' | 'T'<<8 | '3'<<16 | '5'<<24) /* BT35 */ +#define AXI_LOCK_FS_NODE "/dev/btlock" + +static const UINT8 bcm4335a_axi_patch_addr[4] = +{ + 0x00, 0x02, 0x0d, 0x00 +}; + +static const UINT8 bcm4335a_axi_patch[] = +{ + 0x00, 0x02, 0x0d, 0x00, /* bcm4335a_axi_patch_addr */ + 0x70, 0xb5, 0x0c, 0x49, 0x4c, 0xf6, 0x20, 0x30, + 0x8a, 0xf7, 0xbb, 0xf9, 0x01, 0x28, 0x0d, 0xd1, + 0x8a, 0xf7, 0x80, 0xf9, 0x08, 0xb1, 0x04, 0x25, + 0x00, 0xe0, 0x05, 0x25, 0x00, 0x24, 0x03, 0xe0, + 0x8a, 0xf7, 0x74, 0xf9, 0x64, 0x1c, 0xe4, 0xb2, + 0xac, 0x42, 0xf9, 0xd3, 0xbd, 0xe8, 0x70, 0x40, + 0x8a, 0xf7, 0x7f, 0xb9, 0xb0, 0x9b, 0x04, 0x00 +}; + +/******************************************************************************* +** +** Function hw_4335_dl_axi_patch +** +** Description Download 4335Ax/4335B0 AXI BRIDGE patch +** +** Returns TRUE, if fw patch is sent +** FALSE, otherwise +** +*******************************************************************************/ +static UINT8 hw_4335_dl_axi_patch(void) +{ + SendCommand(HCI_VSC_WRITE_RAM, sizeof(bcm4335a_axi_patch), + (UINT8 *) bcm4335a_axi_patch); + read_event(fd, buffer); + + DEBUG0("hw_4335_dl_axi_patch downloading done"); + + SendCommand(HCI_VSC_LAUNCH_RAM, sizeof(bcm4335a_axi_patch_addr), + (UINT8 *) bcm4335a_axi_patch_addr); + read_event(fd, buffer); + + DEBUG0("hw_4335_dl_axi_patch launching done"); + + return TRUE; +} + +/******************************************************************************* +** +** Function hw_4335_release_axi_bridge_lock +** +** Description Notify kernel to release the AXI BRIDGE lock which was +** acquired earlier in rfkill driver when powering on BT +** Controller +** +** Returns None +** +*******************************************************************************/ +void hw_4335_axi_bridge_lock(void) +{ + int fd, ret; + struct btlock lock; + + lock.cookie = AXI_LOCK_COOKIE; + lock.lock = 1; + + fd = open(AXI_LOCK_FS_NODE, O_RDWR); + if (fd >= 0) { - text[i]='='; + ret = write(fd, &lock, sizeof(lock)); + DEBUG0("4335 AXI BRIDGE lock"); + close(fd); } - - for ( i=p+1; i<=PROGRESS_NUM; i++) + else { - text[i]=' '; + DEBUG1("Failed to unlock AXI LOCK -- can't open %s", AXI_LOCK_FS_NODE); } - - - for ( i=0; i<=(PROGRESS_NUM+1); i++) +} + +/******************************************************************************* +** +** Function hw_4335_release_axi_bridge_lock +** +** Description Notify kernel to release the AXI BRIDGE lock which was +** acquired earlier in rfkill driver when powering on BT +** Controller +** +** Returns None +** +*******************************************************************************/ +void hw_4335_release_axi_bridge_lock(void) +{ + int fd, ret; + struct btlock lock; + + lock.cookie = AXI_LOCK_COOKIE; + lock.lock = 0; + + fd = open(AXI_LOCK_FS_NODE, O_RDWR); + if (fd >= 0) { - fprintf(stderr, "%c",text[i]); + ret = write(fd, &lock, sizeof(lock)); + DEBUG0("Releasing 4335 AXI BRIDGE lock"); + close(fd); } - - if( p >= PROGRESS_NUM) - fprintf(stderr, " %6d/%6d\n",val,total); else - fprintf(stderr, " %6d/%6d\r",val,total); -#else - if( val == total) - fprintf(stderr, " %6d/%6d\n",val,total); - else - fprintf(stderr, " %6d/%6d\r",val,total); -#endif + { + DEBUG1("Failed to unlock AXI LOCK -- can't open %s", AXI_LOCK_FS_NODE); + } } +#endif /* (DEPLOY_4335A_AXI_BRIDGE_PATCH == TRUE) */ -UINT8 DownloadPatchram( char *patchram1 ) +UINT8 DownloadPatchram(char *patchram1) { - UINT32 len; - char prm[128] ={0,}; - FILE* pFile = NULL; - - INT32 FileSize=0; - INT32 SentSize=0; - - DEBUG1( "\n%s\n", patchram1); - - /* HCI reset */ - DEBUG0( "HCI reset\n"); - SendCommand(HCI_RESET, 0, NULL); - alarm(1); - read_event(fd, buffer); - alarm(0); - + UINT32 len; + char prm[128] = { 0, }; + FILE *pFile = NULL; + + INT32 FileSize = 0; + INT32 SentSize = 0; + + DEBUG1("\n%s\n", patchram1); + + /* HCI reset */ + DEBUG0("HCI reset\n"); + SendCommand(HCI_RESET, 0, NULL); + alarm(1); + read_event(fd, buffer); + alarm(0); + +#if (DEPLOY_4335A_AXI_BRIDGE_PATCH == TRUE) + char *p_tmp; + + SendCommand(HCI_READ_LOCAL_NAME, 0, NULL); + read_event(fd, buffer); + + p_tmp = strstr((char *)(buffer + 7), "BCM4335"); + DEBUG1( "chip_name [%s]\n", p_tmp); + + if ((p_tmp != NULL) && + ((p_tmp[7] == 'A') /* 4335A */|| + ((p_tmp[7] == 'B') && (p_tmp[8] == '0')) /* 4335B0 */)) { + hw_4335_dl_axi_patch(); + } + hw_4335_release_axi_bridge_lock(); +#endif + #if ( HIGH_SPEED_PATCHRAM_DOWNLOAD == TRUE ) - ChangeBaudRate(3000000); + ChangeBaudRate(921600); #endif - strcpy(prm, patchram1); + strcpy(prm, patchram1); - fprintf(stderr, "Download Start\n"); + fprintf(stderr, "Download Start\n"); - if ((pFile = fopen(prm, "r")) == NULL) - { - fprintf(stderr, "file %s could not be opened, error %d\n", prm, errno); - exit_err(1); - } - FileSize = filesize(prm); - - SendCommand(HCI_BRCM_DOWNLOAD_MINI_DRV, 0, NULL); - read_event(fd, buffer); + if ((pFile = fopen(prm, "r")) == NULL) { + fprintf(stderr, "file %s could not be opened, error %d\n", prm, + errno); + exit_err(1); + } + FileSize = filesize(prm); + + SendCommand(HCI_BRCM_DOWNLOAD_MINI_DRV, 0, NULL); + read_event(fd, buffer); usleep(50000); - while (fread(&buffer[1], sizeof(UINT8), 3 ,pFile)) - { - buffer[0] = 0x01; + while (fread(&buffer[1], sizeof(UINT8), 3, pFile)) { + buffer[0] = 0x01; - len = buffer[3]; + len = buffer[3]; - fread(&buffer[4],sizeof(UINT8),len, pFile); + fread(&buffer[4], sizeof(UINT8), len, pFile); - write(fd, buffer, len + 4); + write(fd, buffer, len + 4); - /* dispaly progress*/ - SentSize += (len + 3); - DisplayProgress(FileSize,SentSize); - /* dispaly progress*/ - - read_event(fd, buffer); + /* dispaly progress */ + SentSize += (len + 3); +#if 0 + DisplayProgress(FileSize, SentSize); +#endif + /* dispaly progress */ - } - fclose(pFile); - - usleep(100000); /*100ms delay */ - - tcflush(fd, TCIOFLUSH); - tcgetattr(fd, &termios); - cfmakeraw(&termios); - termios.c_cflag |= CRTSCTS; - tcsetattr(fd, TCSANOW, &termios); - tcflush(fd, TCIOFLUSH); - tcsetattr(fd, TCSANOW, &termios); - tcflush(fd, TCIOFLUSH); - tcflush(fd, TCIOFLUSH); - cfsetospeed(&termios, B115200); - cfsetispeed(&termios, B115200); - tcsetattr(fd, TCSANOW, &termios); - - /* Send HCI_RESET Command and process event */ - DEBUG0( "HCI reset\n"); - SendCommand(HCI_RESET, 0, NULL); - alarm(1); - read_event(fd, buffer); - alarm(0); - fprintf(stderr,"Download Complete\n"); - - return 0; + read_event(fd, buffer); + + } + fclose(pFile); + + usleep(100000); /*100ms delay */ + + tcflush(fd, TCIOFLUSH); + tcgetattr(fd, &termios); + cfmakeraw(&termios); + termios.c_cflag |= CRTSCTS; + + if (use_two_stop_bits) + termios.c_cflag |= CSTOPB; + + tcsetattr(fd, TCSANOW, &termios); + tcflush(fd, TCIOFLUSH); + tcsetattr(fd, TCSANOW, &termios); + tcflush(fd, TCIOFLUSH); + tcflush(fd, TCIOFLUSH); + cfsetospeed(&termios, B115200); + cfsetispeed(&termios, B115200); + tcsetattr(fd, TCSANOW, &termios); + + /* Send HCI_RESET Command and process event */ + DEBUG0("HCI reset\n"); + SendCommand(HCI_RESET, 0, NULL); + alarm(1); + read_event(fd, buffer); + alarm(0); + fprintf(stderr, "Download Complete\n"); + + return 0; } void SetScanEnable(void) { - UINT8 scan_data[1] ; + UINT8 scan_data[1]; - /* 0x00: No scan enabled */ - /* 0x01: Inquiry scan enabled | Page scan disabled */ - /* 0x02: Inquiry scan disabled | Page scan enabled */ - /* 0x03: Inquiry scan enabled | Page scan enabled */ + /* 0x00: No scan enabled */ + /* 0x01: Inquiry scan enabled | Page scan disabled */ + /* 0x02: Inquiry scan disabled | Page scan enabled */ + /* 0x03: Inquiry scan enabled | Page scan enabled */ - scan_data[0]= 0x03; - SendCommand(HCI_WRITE_SCAN_ENABLE, 1, &scan_data[0]); - read_event(fd, buffer); + scan_data[0] = 0x03; + SendCommand(HCI_WRITE_SCAN_ENABLE, 1, &scan_data[0]); + read_event(fd, buffer); } void SetAudio(void) { - fprintf(stderr,"Write Audio parameter\n"); + fprintf(stderr, "Write Audio parameter\n"); - DEBUG5( "vsc_for_sco_pcm = {%d,%d,%d,%d,%d}\n", vsc_for_sco_pcm[0], - vsc_for_sco_pcm[1],vsc_for_sco_pcm[2], - vsc_for_sco_pcm[3],vsc_for_sco_pcm[4]); + DEBUG5("vsc_for_sco_pcm = {%d,%d,%d,%d,%d}\n", vsc_for_sco_pcm[0], + vsc_for_sco_pcm[1], vsc_for_sco_pcm[2], + vsc_for_sco_pcm[3], vsc_for_sco_pcm[4]); - SendCommand(HCI_BRCM_WRITE_SCO_PCM_INT_PARAM, 5, (UINT8 *)vsc_for_sco_pcm); - read_event(fd, buffer); + SendCommand(HCI_BRCM_WRITE_SCO_PCM_INT_PARAM, 5, + (UINT8 *) vsc_for_sco_pcm); + read_event(fd, buffer); - DEBUG5( "vsc_for_pcm_config = {%d,%d,%d,%d,%d}\n", vsc_for_pcm_config[0], - vsc_for_pcm_config[1], vsc_for_pcm_config[2], - vsc_for_pcm_config[3], vsc_for_pcm_config[4]); + DEBUG5("vsc_for_pcm_config = {%d,%d,%d,%d,%d}\n", vsc_for_pcm_config[0], + vsc_for_pcm_config[1], vsc_for_pcm_config[2], + vsc_for_pcm_config[3], vsc_for_pcm_config[4]); - SendCommand(VSC_WRITE_PCM_DATA_FORMAT_PARAM, 5, (UINT8 *)vsc_for_pcm_config); - read_event(fd, buffer); + SendCommand(VSC_WRITE_PCM_DATA_FORMAT_PARAM, 5, + (UINT8 *) vsc_for_pcm_config); + read_event(fd, buffer); } -void SetPcmConf( UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4 ) +void SetPcmConf(UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4) { - vsc_for_pcm_config[0] = p0; - vsc_for_pcm_config[1] = p1; - vsc_for_pcm_config[2] = p2; - vsc_for_pcm_config[3] = p3; - vsc_for_pcm_config[4] = p4; + vsc_for_pcm_config[0] = p0; + vsc_for_pcm_config[1] = p1; + vsc_for_pcm_config[2] = p2; + vsc_for_pcm_config[3] = p3; + vsc_for_pcm_config[4] = p4; } -void SetScoConf( UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4 ) +void SetScoConf(UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4) { - vsc_for_sco_pcm[0] = p0; - vsc_for_sco_pcm[1] = p1; - vsc_for_sco_pcm[2] = p2; - vsc_for_sco_pcm[3] = p3; - vsc_for_sco_pcm[4] = p4; + vsc_for_sco_pcm[0] = p0; + vsc_for_sco_pcm[1] = p1; + vsc_for_sco_pcm[2] = p2; + vsc_for_sco_pcm[3] = p3; + vsc_for_sco_pcm[4] = p4; } void HCILP_Enable(BOOLEAN on) { - fprintf(stderr,"Set Low Power mode %d\n",on); - UINT8 data[HCI_BRCM_WRITE_SLEEP_MODE_LENGTH] = { - 0x01, /* Sleep Mode algorithm 1 */ - HCILP_IDLE_THRESHOLD, /* Host Idle Treshold in 300ms */ - HCILP_HC_IDLE_THRESHOLD, /* Host Controller Idle Treshold in 300ms */ /* this should be less than scan interval.*/ - HCILP_BT_WAKE_POLARITY, /* BT_WAKE Polarity - 0=Active Low, 1= Active High*/ - HCILP_HOST_WAKE_POLARITY, /* HOST_WAKE Polarity - 0=Active Low, 1= Active High */ - 0x01, /* Allow host Sleep during SCO */ - 0x01, /* Combine Sleep Mode and LPM - The device will not sleep in mode 0 if this flag is set to 1,*/ - 0x00, /* UART_TXD Tri-State : 0x00 = Do not tri-state UART_TXD in sleep mode */ - 0x00, /* NA to Mode 1 */ - 0x00, /* NA to Mode 1 */ - }; - - if(on) - { - data[0] = 0x01; - } - else - { - data[0] = 0x00; - } + fprintf(stderr, "Set Low Power mode %d\n", on); + UINT8 data[HCI_BRCM_WRITE_SLEEP_MODE_LENGTH] = { + 0x01, /* Sleep Mode algorithm 1 */ + HCILP_IDLE_THRESHOLD, /* Host Idle Treshold in 300ms */ + HCILP_HC_IDLE_THRESHOLD, /* Host Controller Idle Treshold in 300ms *//* this should be less than scan interval. */ + HCILP_BT_WAKE_POLARITY, /* BT_WAKE Polarity - 0=Active Low, 1= Active High */ + HCILP_HOST_WAKE_POLARITY, /* HOST_WAKE Polarity - 0=Active Low, 1= Active High */ + 0x01, /* Allow host Sleep during SCO */ + 0x01, /* Combine Sleep Mode and LPM - The device will not sleep in mode 0 if this flag is set to 1, */ + 0x00, /* UART_TXD Tri-State : 0x00 = Do not tri-state UART_TXD in sleep mode */ + 0x00, /* NA to Mode 1 */ + 0x00, /* NA to Mode 1 */ + }; + + if (on) { + data[0] = 0x01; + } else { + data[0] = 0x00; + } - SendCommand(HCI_BRCM_WRITE_SLEEP_MODE, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH, (UINT8 *)data); - read_event(fd, buffer); + SendCommand(HCI_BRCM_WRITE_SLEEP_MODE, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH, + (UINT8 *) data); + read_event(fd, buffer); } UINT32 uart_speed(UINT32 Speed) { - switch (Speed) - { + switch (Speed) { case 115200: return B115200; case 230400: @@ -548,330 +688,347 @@ UINT32 uart_speed(UINT32 Speed) void ChangeBaudRate(UINT32 baudrate) { - UINT8 hci_data[HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - UINT8 uart_clock_24 = 0x2; /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */ - UINT8 uart_clock_48 = 0x1; /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */ + UINT8 hci_data[HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + UINT8 uart_clock_24 = 0x2; /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */ + UINT8 uart_clock_48 = 0x1; /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */ - switch(baudrate) - { - case 115200: - case 230400: - case 460800: - case 921600: - case 1000000: - case 1500000: - case 2000000: - case 2500000: - /* Write UART Clock setting of 24MHz */ - DEBUG0( "Change UART_CLOCK 24Mhz\n"); - SendCommand( VSC_WRITE_UART_CLOCK_SETTING, VSC_WRITE_UART_CLOCK_SETTING_LEN, (UINT8 *)&uart_clock_24); - read_event(fd, buffer); - break; - - case 3000000: - case 4000000: - /* Write UART Clock setting of 48MHz */ - DEBUG0( "Change UART_CLOCK 48Mh\nz"); - SendCommand( VSC_WRITE_UART_CLOCK_SETTING, VSC_WRITE_UART_CLOCK_SETTING_LEN, (UINT8 *)&uart_clock_48); - read_event(fd, buffer); - break; - - default: - fprintf(stderr,"Not Support baudrate = %ld\n", baudrate); - exit_err(1); - break; - } + switch (baudrate) { + case 115200: + case 230400: + case 460800: + case 921600: + case 1000000: + case 1500000: + case 2000000: + case 2500000: + /* Write UART Clock setting of 24MHz */ + DEBUG0("Change UART_CLOCK 24Mhz\n"); + SendCommand(VSC_WRITE_UART_CLOCK_SETTING, + VSC_WRITE_UART_CLOCK_SETTING_LEN, + (UINT8 *) & uart_clock_24); + read_event(fd, buffer); + break; + + case 3000000: + case 4000000: + /* Write UART Clock setting of 48MHz */ + DEBUG0("Change UART_CLOCK 48Mh\nz"); + SendCommand(VSC_WRITE_UART_CLOCK_SETTING, + VSC_WRITE_UART_CLOCK_SETTING_LEN, + (UINT8 *) & uart_clock_48); + read_event(fd, buffer); + break; - hci_data[2] = baudrate & 0xFF; - hci_data[3] = (baudrate >> 8) & 0xFF; - hci_data[4] = (baudrate >> 16) & 0xFF; - hci_data[5] = (baudrate >> 24) & 0xFF; - - DEBUG1( "Change Baudrate %ld\n",baudrate); - - SendCommand( HCI_BRCM_UPDATE_BAUDRATE_CMD, HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH, (UINT8 *)hci_data); - read_event(fd, buffer); - - - tcflush(fd, TCIOFLUSH); - tcgetattr(fd, &termios); - cfmakeraw(&termios); - termios.c_cflag |= CRTSCTS; - tcsetattr(fd, TCSANOW, &termios); - tcflush(fd, TCIOFLUSH); - tcsetattr(fd, TCSANOW, &termios); - tcflush(fd, TCIOFLUSH); - tcflush(fd, TCIOFLUSH); - cfsetospeed(&termios, uart_speed(baudrate)); - cfsetispeed(&termios, uart_speed(baudrate)); - tcsetattr(fd, TCSANOW, &termios); + default: + fprintf(stderr, "Not Support baudrate = %ld\n", baudrate); + exit_err(1); + break; + } + + hci_data[2] = baudrate & 0xFF; + hci_data[3] = (baudrate >> 8) & 0xFF; + hci_data[4] = (baudrate >> 16) & 0xFF; + hci_data[5] = (baudrate >> 24) & 0xFF; + + DEBUG1("Change Baudrate %ld\n", baudrate); + + SendCommand(HCI_BRCM_UPDATE_BAUDRATE_CMD, + HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH, + (UINT8 *) hci_data); + read_event(fd, buffer); + + tcflush(fd, TCIOFLUSH); + tcgetattr(fd, &termios); + cfmakeraw(&termios); + termios.c_cflag |= CRTSCTS; + + if (use_two_stop_bits) + termios.c_cflag |= CSTOPB; + + tcsetattr(fd, TCSANOW, &termios); + tcflush(fd, TCIOFLUSH); + tcsetattr(fd, TCSANOW, &termios); + tcflush(fd, TCIOFLUSH); + tcflush(fd, TCIOFLUSH); + cfsetospeed(&termios, uart_speed(baudrate)); + cfsetispeed(&termios, uart_speed(baudrate)); + tcsetattr(fd, TCSANOW, &termios); } void EnableTestMode(void) { - UINT8 filter_data[] = { 0x02, 0x00, 0x02 }; - - /* bt sleep disable */ - HCILP_Enable(FALSE); + UINT8 filter_data[] = { 0x02, 0x00, 0x02 }; - /* Enable both Inquiry & Page Scans */ - SetScanEnable(); + /* bt sleep disable */ + HCILP_Enable(FALSE); - /* Set Event Filter: Enable Auto Connect */ - SendCommand( HCI_SET_EVENT_FILTER, 0x03, (UINT8 *)filter_data); - read_event(fd, buffer); + /* Enable both Inquiry & Page Scans */ + SetScanEnable(); - /* Enable Device under test */ - SendCommand( HCI_ENABLE_DEV_UNDER_TEST_MODE, 0x0, NULL); - read_event(fd, buffer); + /* Set Event Filter: Enable Auto Connect */ + SendCommand(HCI_SET_EVENT_FILTER, 0x03, (UINT8 *) filter_data); + read_event(fd, buffer); - fprintf(stderr,"Enable Device Under Test\n"); + /* Enable Device under test */ + SendCommand(HCI_ENABLE_DEV_UNDER_TEST_MODE, 0x0, NULL); + read_event(fd, buffer); + + fprintf(stderr, "Enable Device Under Test\n"); } void SetLocalFeatures(void) { - UINT8 *data = NULL; + UINT8 *data = NULL; - DEBUG0("Read Local Feature\n"); - SendCommand(HCI_READ_LOCAL_FEATURES, 0, NULL); - read_event(fd, buffer); + DEBUG0("Read Local Feature\n"); + SendCommand(HCI_READ_LOCAL_FEATURES, 0, NULL); + read_event(fd, buffer); - data = &buffer[7]; + data = &buffer[7]; #if (BCM_DISABLE_RF_PWRCTRL == TRUE) - fprintf(stderr,"Remove Power Control\n"); - data[2] &= 0xFB; /* Power contrel */ + fprintf(stderr, "Remove Power Control\n"); + data[2] &= 0xFB; /* Power contrel */ #endif - DEBUG0("Write Local Feature\n"); - SendCommand(VSC_HCI_CMD_SET_LOC_FEATURES_CMD, 0x08, (UINT8 *)data); - read_event(fd, buffer); + DEBUG0("Write Local Feature\n"); + SendCommand(VSC_HCI_CMD_SET_LOC_FEATURES_CMD, 0x08, (UINT8 *) data); + read_event(fd, buffer); } void EnbleHCI(void) { - int i = N_HCI; - int proto = HCI_UART_H4; + int i = N_HCI; + int proto = HCI_UART_H4; + + if (ioctl(fd, TIOCSETD, &i) < 0) { + fprintf(stderr, "Can't set line discipline\n"); + return; + } + + if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) { + fprintf(stderr, "Can't set hci protocol\n"); + return; + } + fprintf(stderr, "Done setting line discpline\n"); + return; - if (ioctl(fd, TIOCSETD, &i) < 0) - { - fprintf(stderr, "Can't set line discipline\n"); - return; - } - - if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) - { - fprintf(stderr, "Can't set hci protocol\n"); - return; - } - fprintf(stderr, "Done setting line discpline\n"); - return; - } -void print_usage( void ) + +void print_usage(void) { - fprintf(stderr,"\n"); - fprintf(stderr,"BRCM BT tool for Linux release %s\n",RELEASE_DATE); - fprintf(stderr,"\n"); - fprintf(stderr," Usage: bcmtool [command parameter],....\n\n"); - fprintf(stderr," -FILE Patchram file name EX) -FILE=BCM43xx_xxx.hcd\n"); - fprintf(stderr," -BAUD Set Baudrate EX) -BAUD=3000000\n"); - fprintf(stderr," -ADDR BD addr file name EX) -ADDR=.bdaddr\n"); - fprintf(stderr," -SCO Enable SCO/PCM config EX) -SCO\n"); - fprintf(stderr," -SETSCO SCO/PCM values verify EX) -SETSCO=0,1,0,1,1,0,0,3,3,0\n"); - fprintf(stderr," -LP Enable Low power EX) -LP\n"); - fprintf(stderr," -FEATURE Set local Feature EX) -FEATURE\n"); - fprintf(stderr," -DUT Enable DUT mode(do not use with -LP) EX) -DUT\n"); - fprintf(stderr," -ATTACH Attach BT controller to BlueZ stack EX) -ATTACH\n"); - fprintf(stderr," -DEBUG Debug message EX) -DEBUG\n"); - fprintf(stderr,"\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "BRCM BT tool for Linux release %s\n", RELEASE_DATE); + fprintf(stderr, "\n"); + fprintf(stderr, + " Usage: bcmtool [command parameter],....\n\n"); + fprintf(stderr, + " -FILE Patchram file name EX) -FILE=BCM43xx_xxx.hcd\n"); + fprintf(stderr, + " -BAUD Set Baudrate EX) -BAUD=3000000\n"); + fprintf(stderr, + " -ADDR BD addr file name EX) -ADDR=.bdaddr\n"); + fprintf(stderr, " -SCO Enable SCO/PCM config EX) -SCO\n"); + fprintf(stderr, + " -SETSCO SCO/PCM values verify EX) -SETSCO=0,1,0,1,1,0,0,3,3,0\n"); + fprintf(stderr, " -LP Enable Low power EX) -LP\n"); + fprintf(stderr, " -FEATURE Set local Feature EX) -FEATURE\n"); + fprintf(stderr, + " -DUT Enable DUT mode(do not use with -LP) EX) -DUT\n"); + fprintf(stderr, + " -ATTACH Attach BT controller to BlueZ stack EX) -ATTACH\n"); + fprintf(stderr, " -DEBUG Debug message EX) -DEBUG\n"); + fprintf(stderr, " -CSTOPB Set two stop bits for tty EX) -CSTOPB\n"); + fprintf(stderr, "\n"); } int main(int argc, char *argv[]) { - UINT8 i = 0; - - if (argc < 2) - { - print_usage(); - exit(1); - } - else - { - fprintf(stderr,"BRCM BT tool for Linux release %s\n",RELEASE_DATE); - } - - /* Open dev port */ - if ((fd = open(argv[1], O_RDWR | O_NOCTTY)) == -1) - { - fprintf(stderr, "port %s could not be opened, error %d\n", argv[1], errno); - exit(2); - } - - tcflush(fd, TCIOFLUSH); - tcgetattr(fd, &termios); - cfmakeraw(&termios); - termios.c_cflag |= CRTSCTS; - tcsetattr(fd, TCSANOW, &termios); - tcflush(fd, TCIOFLUSH); - tcsetattr(fd, TCSANOW, &termios); - tcflush(fd, TCIOFLUSH); - tcflush(fd, TCIOFLUSH); - cfsetospeed(&termios, B115200); - cfsetispeed(&termios, B115200); - tcsetattr(fd, TCSANOW, &termios); - - signal(SIGALRM, expired); - - for( i=2; i