summaryrefslogtreecommitdiff
authorTellen Yu <tellen.yu@amlogic.com>2015-11-04 10:27:29 (GMT)
committer Tellen Yu <tellen.yu@amlogic.com>2015-11-04 10:43:37 (GMT)
commit662261a9faf9915cc65a51ccf50e66f15a8d95c3 (patch)
treea10ada820a5f1c5f10829d4240cde0a7dc565453
parent1fe4015dcc172798cf88972723f79c86d1552186 (diff)
downloadlibbt-662261a9faf9915cc65a51ccf50e66f15a8d95c3.zip
libbt-662261a9faf9915cc65a51ccf50e66f15a8d95c3.tar.gz
libbt-662261a9faf9915cc65a51ccf50e66f15a8d95c3.tar.bz2
merge hardware/broadcom/libbt to m-amlogic
Change-Id: Id10e2ddca5a4c62a3e34a5d20df7d48837bcc484
Diffstat
-rw-r--r--Android.mk49
-rw-r--r--conf/asus/grouper/Android.mk14
-rw-r--r--conf/asus/grouper/bt_vendor.conf5
-rw-r--r--conf/meson/Android.mk14
-rw-r--r--conf/meson/bt_vendor.conf5
-rw-r--r--conf/moto/wingray/Android.mk14
-rw-r--r--conf/moto/wingray/bt_vendor.conf5
-rw-r--r--conf/samsung/crespo/Android.mk14
-rw-r--r--conf/samsung/crespo/bt_vendor.conf5
-rw-r--r--conf/samsung/crespo4g/Android.mk14
-rw-r--r--conf/samsung/crespo4g/bt_vendor.conf5
-rw-r--r--conf/samsung/maguro/Android.mk14
-rw-r--r--conf/samsung/maguro/bt_vendor.conf5
-rwxr-xr-xgen-buildcfg.sh25
-rwxr-xr-xinclude/bt_vendor_brcm.h103
-rw-r--r--[-rwxr-xr-x]include/vnd_40183_lpm.txt0
-rw-r--r--include/vnd_angler.txt17
-rw-r--r--include/vnd_anthias.txt10
-rw-r--r--include/vnd_bass.txt16
-rw-r--r--include/vnd_carp.txt14
-rw-r--r--include/vnd_crespo.txt8
-rw-r--r--include/vnd_crespo4g.txt8
-rw-r--r--include/vnd_dory.txt14
-rw-r--r--include/vnd_dragon.txt9
-rw-r--r--include/vnd_flounder.txt10
-rw-r--r--include/vnd_flounder64.txt10
-rw-r--r--include/vnd_flounder_lte.txt10
-rw-r--r--include/vnd_fugu.txt11
-rw-r--r--[-rwxr-xr-x]include/vnd_generic.txt1
-rw-r--r--[-rwxr-xr-x]include/vnd_generic_x86.txt1
-rw-r--r--include/vnd_grouper.txt10
-rw-r--r--include/vnd_hammerhead.txt15
-rw-r--r--include/vnd_lenok.txt16
-rw-r--r--include/vnd_maguro.txt8
-rw-r--r--include/vnd_mako.txt8
-rw-r--r--include/vnd_manta.txt10
-rw-r--r--[-rwxr-xr-x]include/vnd_meson6.txt0
-rw-r--r--[-rwxr-xr-x]include/vnd_meson6_lpm.txt0
-rw-r--r--[-rwxr-xr-x]include/vnd_meson8.txt0
-rw-r--r--[-rwxr-xr-x]include/vnd_meson8_lpm.txt0
-rw-r--r--include/vnd_nemo.txt16
-rw-r--r--include/vnd_phantasm.txt8
-rw-r--r--include/vnd_puffer.txt15
-rw-r--r--include/vnd_shamu.txt14
-rw-r--r--include/vnd_smelt.txt14
-rw-r--r--include/vnd_sparrow.txt10
-rw-r--r--include/vnd_sprat.txt21
-rw-r--r--include/vnd_stingray.txt8
-rw-r--r--include/vnd_sturgeon.txt14
-rw-r--r--include/vnd_tetra.txt15
-rw-r--r--include/vnd_tilapia.txt10
-rw-r--r--include/vnd_toro.txt9
-rw-r--r--include/vnd_tuna.txt9
-rw-r--r--include/vnd_wingray.txt8
-rw-r--r--include/vnd_wren.txt10
-rwxr-xr-xsrc/bt_vendor_brcm.c23
-rwxr-xr-xsrc/hardware.c543
-rwxr-xr-xsrc/upio.c93
-rwxr-xr-xsrc/userial_vendor.c29
-rwxr-xr-xvnd_buildcfg.mk4
60 files changed, 1223 insertions, 147 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..036fa7d
--- a/dev/null
+++ b/Android.mk
@@ -0,0 +1,49 @@
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(BOARD_HAVE_BLUETOOTH_BCM),)
+
+include $(CLEAR_VARS)
+
+BDROID_DIR := $(TOP_DIR)system/bt
+
+LOCAL_SRC_FILES := \
+ src/bt_vendor_brcm.c \
+ src/hardware.c \
+ src/userial_vendor.c \
+ src/upio.c \
+ src/conf.c
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ $(BDROID_DIR)/hci/include
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ liblog
+
+LOCAL_MODULE := libbt-vendor
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MODULE_OWNER := broadcom
+LOCAL_PROPRIETARY_MODULE := true
+
+include $(LOCAL_PATH)/vnd_buildcfg.mk
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(LOCAL_PATH)/conf/meson/Android.mk
+
+ifeq ($(TARGET_PRODUCT), full_maguro)
+ include $(LOCAL_PATH)/conf/samsung/maguro/Android.mk
+endif
+ifeq ($(TARGET_PRODUCT), full_crespo)
+ include $(LOCAL_PATH)/conf/samsung/crespo/Android.mk
+endif
+ifeq ($(TARGET_PRODUCT), full_crespo4g)
+ include $(LOCAL_PATH)/conf/samsung/crespo4g/Android.mk
+endif
+ifeq ($(TARGET_PRODUCT), full_wingray)
+ include $(LOCAL_PATH)/conf/moto/wingray/Android.mk
+endif
+
+endif # BOARD_HAVE_BLUETOOTH_BCM
diff --git a/conf/asus/grouper/Android.mk b/conf/asus/grouper/Android.mk
new file mode 100644
index 0000000..974e213
--- a/dev/null
+++ b/conf/asus/grouper/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bt_vendor.conf
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth
+
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
+
diff --git a/conf/asus/grouper/bt_vendor.conf b/conf/asus/grouper/bt_vendor.conf
new file mode 100644
index 0000000..94fa0cd
--- a/dev/null
+++ b/conf/asus/grouper/bt_vendor.conf
@@ -0,0 +1,5 @@
+# UART device port where Bluetooth controller is attached
+UartPort = /dev/ttyHS2
+
+# Firmware patch file location
+FwPatchFilePath = /etc/firmware/
diff --git a/conf/meson/Android.mk b/conf/meson/Android.mk
new file mode 100644
index 0000000..974e213
--- a/dev/null
+++ b/conf/meson/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bt_vendor.conf
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth
+
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
+
diff --git a/conf/meson/bt_vendor.conf b/conf/meson/bt_vendor.conf
new file mode 100644
index 0000000..659ad6e
--- a/dev/null
+++ b/conf/meson/bt_vendor.conf
@@ -0,0 +1,5 @@
+# UART device port where Bluetooth controller is attached
+UartPort = /dev/ttyS1
+
+# Firmware patch file location
+FwPatchFilePath = /etc/bluetooth/
diff --git a/conf/moto/wingray/Android.mk b/conf/moto/wingray/Android.mk
new file mode 100644
index 0000000..974e213
--- a/dev/null
+++ b/conf/moto/wingray/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bt_vendor.conf
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth
+
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
+
diff --git a/conf/moto/wingray/bt_vendor.conf b/conf/moto/wingray/bt_vendor.conf
new file mode 100644
index 0000000..94fa0cd
--- a/dev/null
+++ b/conf/moto/wingray/bt_vendor.conf
@@ -0,0 +1,5 @@
+# UART device port where Bluetooth controller is attached
+UartPort = /dev/ttyHS2
+
+# Firmware patch file location
+FwPatchFilePath = /etc/firmware/
diff --git a/conf/samsung/crespo/Android.mk b/conf/samsung/crespo/Android.mk
new file mode 100644
index 0000000..974e213
--- a/dev/null
+++ b/conf/samsung/crespo/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bt_vendor.conf
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth
+
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
+
diff --git a/conf/samsung/crespo/bt_vendor.conf b/conf/samsung/crespo/bt_vendor.conf
new file mode 100644
index 0000000..1f471ca
--- a/dev/null
+++ b/conf/samsung/crespo/bt_vendor.conf
@@ -0,0 +1,5 @@
+# UART device port where Bluetooth controller is attached
+UartPort = /dev/s3c2410_serial0
+
+# Firmware patch file location
+FwPatchFilePath = /vendor/firmware/
diff --git a/conf/samsung/crespo4g/Android.mk b/conf/samsung/crespo4g/Android.mk
new file mode 100644
index 0000000..974e213
--- a/dev/null
+++ b/conf/samsung/crespo4g/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bt_vendor.conf
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth
+
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
+
diff --git a/conf/samsung/crespo4g/bt_vendor.conf b/conf/samsung/crespo4g/bt_vendor.conf
new file mode 100644
index 0000000..1f471ca
--- a/dev/null
+++ b/conf/samsung/crespo4g/bt_vendor.conf
@@ -0,0 +1,5 @@
+# UART device port where Bluetooth controller is attached
+UartPort = /dev/s3c2410_serial0
+
+# Firmware patch file location
+FwPatchFilePath = /vendor/firmware/
diff --git a/conf/samsung/maguro/Android.mk b/conf/samsung/maguro/Android.mk
new file mode 100644
index 0000000..974e213
--- a/dev/null
+++ b/conf/samsung/maguro/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bt_vendor.conf
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth
+
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
+
diff --git a/conf/samsung/maguro/bt_vendor.conf b/conf/samsung/maguro/bt_vendor.conf
new file mode 100644
index 0000000..d5547eb
--- a/dev/null
+++ b/conf/samsung/maguro/bt_vendor.conf
@@ -0,0 +1,5 @@
+# UART device port where Bluetooth controller is attached
+UartPort = /dev/ttyO1
+
+# Firmware patch file location
+FwPatchFilePath = /vendor/firmware/
diff --git a/gen-buildcfg.sh b/gen-buildcfg.sh
new file mode 100755
index 0000000..40c01f4
--- a/dev/null
+++ b/gen-buildcfg.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+if [[ "" == "$2" ]]
+then
+ echo "Usage: $0 <in-file> <out-file>"
+ exit 1
+fi
+
+if [ ! -f "$1" ]
+then
+ echo "Error: Can't find input file $1..."
+ exit 2
+fi
+
+DATE=`/usr/bin/env date`
+BASE=`basename $2`
+BASE=`echo ${BASE} | tr "[:lower:]" "[:upper:]"`
+BASE=`echo ${BASE} | sed -e "s/\\./_/"`
+PROTECT="_${BASE}"
+
+echo "/* Auto-generated from $1 on ${DATE} */" > $2
+echo "#ifndef ${PROTECT}" >> $2
+echo "#define ${PROTECT}" >> $2
+sed -e '/^#/d' -e '/^$$/d' -e '/# Makefile only$$/d' -e 's/^/#define /' -e 's/=/ /' $1 >> $2
+echo "#endif" >> $2
diff --git a/include/bt_vendor_brcm.h b/include/bt_vendor_brcm.h
index b8b693b..545e76e 100755
--- a/include/bt_vendor_brcm.h
+++ b/include/bt_vendor_brcm.h
@@ -56,16 +56,16 @@
/* Device port name where Bluetooth controller attached */
#ifndef BLUETOOTH_UART_DEVICE_PORT
-#define BLUETOOTH_UART_DEVICE_PORT "/dev/ttyS1" /* maguro */
+#define BLUETOOTH_UART_DEVICE_PORT "/dev/ttyO1" /* maguro */
#endif
/* Location of firmware patch files */
#ifndef FW_PATCHFILE_LOCATION
-#define FW_PATCHFILE_LOCATION "/etc/bluetooth/" /* maguro */
+#define FW_PATCHFILE_LOCATION "/vendor/firmware/" /* maguro */
#endif
#ifndef UART_TARGET_BAUD_RATE
-#define UART_TARGET_BAUD_RATE 2000000
+#define UART_TARGET_BAUD_RATE 3000000
#endif
/* The millisecond delay pauses on HCI transport after firmware patches
@@ -79,7 +79,7 @@
* baud.
*/
#ifndef FW_PATCH_SETTLEMENT_DELAY_MS
-#define FW_PATCH_SETTLEMENT_DELAY_MS 200
+#define FW_PATCH_SETTLEMENT_DELAY_MS 0
#endif
/* The Bluetooth Device Aaddress source switch:
@@ -106,7 +106,7 @@
1: UART with Host wake/BT wake out of band signals
*/
#ifndef LPM_SLEEP_MODE
-#define LPM_SLEEP_MODE 0
+#define LPM_SLEEP_MODE 1
#endif
/* Host Stack Idle Threshold in 300ms or 25ms
@@ -202,14 +202,34 @@
#define BT_WAKE_VIA_USERIAL_IOCTL FALSE
#endif
+/* BT_WAKE_USERIAL_LDISC
+
+ Use line discipline if the BT_WAKE control is in line discipline
+*/
+#ifndef BT_WAKE_USERIAL_LDISC
+#define BT_WAKE_USERIAL_LDISC FALSE
+#endif
+
/* BT_WAKE_VIA_PROC
-
+
LPM & BT_WAKE control through PROC nodes
- */
+*/
#ifndef BT_WAKE_VIA_PROC
#define BT_WAKE_VIA_PROC FALSE
#endif
+#ifndef BT_WAKE_VIA_PROC_NOTIFY_DEASSERT
+#define BT_WAKE_VIA_PROC_NOTIFY_DEASSERT FALSE
+#endif
+
+/* N_BRCM_HCI
+
+ UART ioctl line discipline
+*/
+#ifndef N_BRCM_HCI
+#define N_BRCM_HCI 25
+#endif
+
/* SCO_CFG_INCLUDED
Do SCO configuration by default. If the firmware patch had been embedded
@@ -224,9 +244,22 @@
#define SCO_USE_I2S_INTERFACE FALSE
#endif
-#if (SCO_USE_I2S_INTERFACE == TRUE)
#define SCO_I2SPCM_PARAM_SIZE 4
+/* SCO_WBS_SAMPLE_RATE
+ 0 : 8K
+ 1 : 16K
+ 2 : 4K
+ This macro is used for setting WBS sampling rate for a SCO connection
+ If the mobile network supports WBS, we need to use 16KHz as default
+ but if the platform doesn't support 16KHz, the sample rate can be
+ overriden to 8KHz by setting this to 0.
+*/
+#ifndef SCO_WBS_SAMPLE_RATE
+#define SCO_WBS_SAMPLE_RATE 1
+#endif
+
+
/* SCO_I2SPCM_IF_MODE - 0=Disable, 1=Enable */
#ifndef SCO_I2SPCM_IF_MODE
#define SCO_I2SPCM_IF_MODE 1
@@ -258,7 +291,18 @@
#ifndef SCO_I2SPCM_IF_CLOCK_RATE
#define SCO_I2SPCM_IF_CLOCK_RATE 1
#endif
-#endif // SCO_USE_I2S_INTERFACE
+
+/* SCO_I2SPCM_IF_CLOCK_RATE4WBS
+
+ 0 : 128K
+ 1 : 256K
+ 2 : 512K
+ 3 : 1024K
+ 4 : 2048K
+*/
+#ifndef SCO_I2SPCM_IF_CLOCK_RATE4WBS
+#define SCO_I2SPCM_IF_CLOCK_RATE4WBS 2
+#endif
#define SCO_PCM_PARAM_SIZE 5
@@ -276,6 +320,8 @@
/* SCO_PCM_IF_CLOCK_RATE
+ NOTICE: suggested to be consistent with SCO_I2SPCM_IF_CLOCK_RATE
+
0 : 128K
1 : 256K
2 : 512K
@@ -283,22 +329,35 @@
4 : 2048K
*/
#ifndef SCO_PCM_IF_CLOCK_RATE
-#define SCO_PCM_IF_CLOCK_RATE 0
+#define SCO_PCM_IF_CLOCK_RATE 4
#endif
/* SCO_PCM_IF_FRAME_TYPE - 0=Short, 1=Long */
#ifndef SCO_PCM_IF_FRAME_TYPE
-#define SCO_PCM_IF_FRAME_TYPE 1
+#define SCO_PCM_IF_FRAME_TYPE 0
#endif
-/* SCO_PCM_IF_SYNC_MODE - 0=Slave, 1=Master */
+/* SCO_PCM_IF_SYNC_MODE
+
+ NOTICE: in most usage cases the value will be the same as
+ SCO_PCM_IF_CLOCK_MODE setting
+
+ 0 : Slave
+ 1 : Master
+*/
#ifndef SCO_PCM_IF_SYNC_MODE
-#define SCO_PCM_IF_SYNC_MODE 1
+#define SCO_PCM_IF_SYNC_MODE 0
#endif
-/* SCO_PCM_IF_CLOCK_MODE - 0=Slave, 1=Master */
+/* SCO_PCM_IF_CLOCK_MODE
+
+ NOTICE: suggested to be consistent with SCO_I2SPCM_IF_ROLE
+
+ 0 : Slave
+ 1 : Master
+*/
#ifndef SCO_PCM_IF_CLOCK_MODE
-#define SCO_PCM_IF_CLOCK_MODE 1
+#define SCO_PCM_IF_CLOCK_MODE 0
#endif
#define PCM_DATA_FORMAT_PARAM_SIZE 5
@@ -318,7 +377,7 @@
if Fill_Method is set to programmable
*/
#ifndef PCM_DATA_FMT_FILL_BITS
-#define PCM_DATA_FMT_FILL_BITS 3
+#define PCM_DATA_FMT_FILL_BITS 0
#endif
/* PCM_DATA_FMT_FILL_METHOD
@@ -349,11 +408,23 @@
#define PCM_DATA_FMT_JUSTIFY_MODE 0
#endif
+/* HW_END_WITH_HCI_RESET
+
+ Sample code implementation of sending a HCI_RESET command during the epilog
+ process. It calls back to the callers after command complete of HCI_RESET
+ is received.
+*/
+#ifndef HW_END_WITH_HCI_RESET
+#define HW_END_WITH_HCI_RESET TRUE
+#endif
+
/******************************************************************************
** Extern variables and functions
******************************************************************************/
extern bt_vendor_callbacks_t *bt_vendor_cbacks;
+extern int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state);
+
#endif /* BT_VENDOR_BRCM_H */
diff --git a/include/vnd_40183_lpm.txt b/include/vnd_40183_lpm.txt
index 3ba3141..3ba3141 100755..100644
--- a/include/vnd_40183_lpm.txt
+++ b/include/vnd_40183_lpm.txt
diff --git a/include/vnd_angler.txt b/include/vnd_angler.txt
new file mode 100644
index 0000000..103b656
--- a/dev/null
+++ b/include/vnd_angler.txt
@@ -0,0 +1,17 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS0"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+BT_WAKE_VIA_PROC_NOTIFY_DEASSERT=TRUE
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 4000
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_HC_IDLE_THRESHOLD = 24
+LPM_IDLE_THRESHOLD = 24
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_anthias.txt b/include/vnd_anthias.txt
new file mode 100644
index 0000000..f1a574c
--- a/dev/null
+++ b/include/vnd_anthias.txt
@@ -0,0 +1,10 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS0"
+FW_PATCHFILE_LOCATION = "/system/etc/firmware/bt"
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+BTVND_DBG = FALSE
+BTHW_DBG = FALSE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+BT_WAKE_VIA_PROC = TRUE
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 0
diff --git a/include/vnd_bass.txt b/include/vnd_bass.txt
new file mode 100644
index 0000000..a96c1a5
--- a/dev/null
+++ b/include/vnd_bass.txt
@@ -0,0 +1,16 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS99"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+LPM_IDLE_THRESHOLD = 10
+LPM_HC_IDLE_THRESHOLD = 10
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_carp.txt b/include/vnd_carp.txt
new file mode 100644
index 0000000..bcd0d0e
--- a/dev/null
+++ b/include/vnd_carp.txt
@@ -0,0 +1,14 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS6"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_crespo.txt b/include/vnd_crespo.txt
new file mode 100644
index 0000000..2ba0780
--- a/dev/null
+++ b/include/vnd_crespo.txt
@@ -0,0 +1,8 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/s3c2410_serial0"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_PCM_IF_CLOCK_RATE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_crespo4g.txt b/include/vnd_crespo4g.txt
new file mode 100644
index 0000000..2ba0780
--- a/dev/null
+++ b/include/vnd_crespo4g.txt
@@ -0,0 +1,8 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/s3c2410_serial0"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_PCM_IF_CLOCK_RATE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_dory.txt b/include/vnd_dory.txt
new file mode 100644
index 0000000..062273b
--- a/dev/null
+++ b/include/vnd_dory.txt
@@ -0,0 +1,14 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS99"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_dragon.txt b/include/vnd_dragon.txt
new file mode 100644
index 0000000..1d601c1
--- a/dev/null
+++ b/include/vnd_dragon.txt
@@ -0,0 +1,9 @@
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_PCM_IF_CLOCK_RATE = 3
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+BT_WAKE_VIA_PROC = FALSE
+BT_WAKE_VIA_USERIAL_IOCTL = TRUE
+UPIO_DBG = FALSE
diff --git a/include/vnd_flounder.txt b/include/vnd_flounder.txt
new file mode 100644
index 0000000..a366b9c
--- a/dev/null
+++ b/include/vnd_flounder.txt
@@ -0,0 +1,10 @@
+VENDOR_BTWRITE_PROC_NODE = "/proc/bluetooth/sleep/lpm"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_PCM_IF_CLOCK_RATE = 3
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+BT_WAKE_VIA_PROC_NOTIFY_DEASSERT = TRUE
+BT_WAKE_VIA_PROC = TRUE
+UPIO_DBG = FALSE
diff --git a/include/vnd_flounder64.txt b/include/vnd_flounder64.txt
new file mode 100644
index 0000000..a366b9c
--- a/dev/null
+++ b/include/vnd_flounder64.txt
@@ -0,0 +1,10 @@
+VENDOR_BTWRITE_PROC_NODE = "/proc/bluetooth/sleep/lpm"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_PCM_IF_CLOCK_RATE = 3
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+BT_WAKE_VIA_PROC_NOTIFY_DEASSERT = TRUE
+BT_WAKE_VIA_PROC = TRUE
+UPIO_DBG = FALSE
diff --git a/include/vnd_flounder_lte.txt b/include/vnd_flounder_lte.txt
new file mode 100644
index 0000000..a366b9c
--- a/dev/null
+++ b/include/vnd_flounder_lte.txt
@@ -0,0 +1,10 @@
+VENDOR_BTWRITE_PROC_NODE = "/proc/bluetooth/sleep/lpm"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_PCM_IF_CLOCK_RATE = 3
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+BT_WAKE_VIA_PROC_NOTIFY_DEASSERT = TRUE
+BT_WAKE_VIA_PROC = TRUE
+UPIO_DBG = FALSE
diff --git a/include/vnd_fugu.txt b/include/vnd_fugu.txt
new file mode 100644
index 0000000..fa04a78
--- a/dev/null
+++ b/include/vnd_fugu.txt
@@ -0,0 +1,11 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyMFD0"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = FALSE
+BT_WAKE_VIA_USERIAL_IOCTL = FALSE
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+SCO_PCM_IF_CLOCK_RATE = 2
+USE_CONTROLLER_BDADDR = FALSE
diff --git a/include/vnd_generic.txt b/include/vnd_generic.txt
index 43e790c..18964f2 100755..100644
--- a/include/vnd_generic.txt
+++ b/include/vnd_generic.txt
@@ -1,6 +1,5 @@
BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
FW_PATCHFILE_LOCATION = "/vendor/firmware/"
-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
LPM_IDLE_TIMEOUT_MULTIPLE = 5
SCO_USE_I2S_INTERFACE = TRUE
BTVND_DBG = FALSE
diff --git a/include/vnd_generic_x86.txt b/include/vnd_generic_x86.txt
index 43e790c..18964f2 100755..100644
--- a/include/vnd_generic_x86.txt
+++ b/include/vnd_generic_x86.txt
@@ -1,6 +1,5 @@
BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
FW_PATCHFILE_LOCATION = "/vendor/firmware/"
-BT_WAKE_VIA_USERIAL_IOCTL = TRUE
LPM_IDLE_TIMEOUT_MULTIPLE = 5
SCO_USE_I2S_INTERFACE = TRUE
BTVND_DBG = FALSE
diff --git a/include/vnd_grouper.txt b/include/vnd_grouper.txt
new file mode 100644
index 0000000..3e4d71c
--- a/dev/null
+++ b/include/vnd_grouper.txt
@@ -0,0 +1,10 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2"
+FW_PATCHFILE_LOCATION = "/etc/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+SCO_PCM_IF_CLOCK_RATE = 2
+USE_CONTROLLER_BDADDR = TRUE
diff --git a/include/vnd_hammerhead.txt b/include/vnd_hammerhead.txt
new file mode 100644
index 0000000..20013e9
--- a/dev/null
+++ b/include/vnd_hammerhead.txt
@@ -0,0 +1,15 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS99"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 4000
+UART_TARGET_BAUD_RATE = 4000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_WBS_SAMPLE_RATE = 0
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_lenok.txt b/include/vnd_lenok.txt
new file mode 100644
index 0000000..a96c1a5
--- a/dev/null
+++ b/include/vnd_lenok.txt
@@ -0,0 +1,16 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS99"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+LPM_IDLE_THRESHOLD = 10
+LPM_HC_IDLE_THRESHOLD = 10
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_maguro.txt b/include/vnd_maguro.txt
new file mode 100644
index 0000000..18964f2
--- a/dev/null
+++ b/include/vnd_maguro.txt
@@ -0,0 +1,8 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = TRUE
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_mako.txt b/include/vnd_mako.txt
new file mode 100644
index 0000000..18964f2
--- a/dev/null
+++ b/include/vnd_mako.txt
@@ -0,0 +1,8 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = TRUE
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_manta.txt b/include/vnd_manta.txt
new file mode 100644
index 0000000..b2809d1
--- a/dev/null
+++ b/include/vnd_manta.txt
@@ -0,0 +1,10 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttySAC0"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+UART_TARGET_BAUD_RATE = 921600
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = TRUE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_meson6.txt b/include/vnd_meson6.txt
index fc87a57..fc87a57 100755..100644
--- a/include/vnd_meson6.txt
+++ b/include/vnd_meson6.txt
diff --git a/include/vnd_meson6_lpm.txt b/include/vnd_meson6_lpm.txt
index 3ba3141..3ba3141 100755..100644
--- a/include/vnd_meson6_lpm.txt
+++ b/include/vnd_meson6_lpm.txt
diff --git a/include/vnd_meson8.txt b/include/vnd_meson8.txt
index fc87a57..fc87a57 100755..100644
--- a/include/vnd_meson8.txt
+++ b/include/vnd_meson8.txt
diff --git a/include/vnd_meson8_lpm.txt b/include/vnd_meson8_lpm.txt
index 3ba3141..3ba3141 100755..100644
--- a/include/vnd_meson8_lpm.txt
+++ b/include/vnd_meson8_lpm.txt
diff --git a/include/vnd_nemo.txt b/include/vnd_nemo.txt
new file mode 100644
index 0000000..a96c1a5
--- a/dev/null
+++ b/include/vnd_nemo.txt
@@ -0,0 +1,16 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS99"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+LPM_IDLE_THRESHOLD = 10
+LPM_HC_IDLE_THRESHOLD = 10
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_phantasm.txt b/include/vnd_phantasm.txt
new file mode 100644
index 0000000..18964f2
--- a/dev/null
+++ b/include/vnd_phantasm.txt
@@ -0,0 +1,8 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = TRUE
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_puffer.txt b/include/vnd_puffer.txt
new file mode 100644
index 0000000..e12bb75
--- a/dev/null
+++ b/include/vnd_puffer.txt
@@ -0,0 +1,15 @@
+BT_WAKE_VIA_USERIAL_IOCTL = TRUE
+BT_WAKE_USERIAL_LDISC = TRUE
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_IDLE_THRESHOLD = 2
+LPM_HC_IDLE_THRESHOLD = 2
+SCO_I2SPCM_IF_ROLE = 0
+SCO_I2SPCM_IF_CLOCK_RATE = 0
+SCO_PCM_IF_CLOCK_RATE = 0
+SCO_I2SPCM_IF_CLOCK_RATE4WBS = 1
+BTVND_DBG = FALSE
+BTHW_DBG = FALSE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_shamu.txt b/include/vnd_shamu.txt
new file mode 100644
index 0000000..1b93b2a
--- a/dev/null
+++ b/include/vnd_shamu.txt
@@ -0,0 +1,14 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS0"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 4000
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_smelt.txt b/include/vnd_smelt.txt
new file mode 100644
index 0000000..bcd0d0e
--- a/dev/null
+++ b/include/vnd_smelt.txt
@@ -0,0 +1,14 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS6"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_sparrow.txt b/include/vnd_sparrow.txt
new file mode 100644
index 0000000..db52a83
--- a/dev/null
+++ b/include/vnd_sparrow.txt
@@ -0,0 +1,10 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS0"
+FW_PATCHFILE_LOCATION = "/system/etc/firmware/bt"
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+BT_WAKE_VIA_PROC = TRUE
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 0
diff --git a/include/vnd_sprat.txt b/include/vnd_sprat.txt
new file mode 100644
index 0000000..c1465c8
--- a/dev/null
+++ b/include/vnd_sprat.txt
@@ -0,0 +1,21 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS0"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_MODE = 0
+SCO_I2SPCM_IF_ROLE = 0
+SCO_I2SPCM_IF_SAMPLE_RATE = 0
+SCO_I2SPCM_IF_CLOCK_RATE = 4
+SCO_I2SPCM_IF_CLOCK_RATE4WBS = 4
+SCO_PCM_ROUTING = 0
+SCO_PCM_IF_CLOCK_RATE = 4
+SCO_PCM_IF_FRAME_TYPE = 0
+SCO_PCM_IF_SYNC_MODE = 0
+SCO_PCM_IF_CLOCK_MODE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = FALSE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+BT_WAKE_VIA_PROC = TRUE
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 700
diff --git a/include/vnd_stingray.txt b/include/vnd_stingray.txt
new file mode 100644
index 0000000..f5eb1d0
--- a/dev/null
+++ b/include/vnd_stingray.txt
@@ -0,0 +1,8 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2"
+FW_PATCHFILE_LOCATION = "/etc/firmware/"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+SCO_PCM_IF_CLOCK_RATE = 2
diff --git a/include/vnd_sturgeon.txt b/include/vnd_sturgeon.txt
new file mode 100644
index 0000000..ae8177d
--- a/dev/null
+++ b/include/vnd_sturgeon.txt
@@ -0,0 +1,14 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS0"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+SCO_USE_I2S_INTERFACE = FALSE
+SCO_I2SPCM_IF_ROLE = 0
+BTVND_DBG = FALSE
+BTHW_DBG = FALSE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 800
diff --git a/include/vnd_tetra.txt b/include/vnd_tetra.txt
new file mode 100644
index 0000000..fc3f88a
--- a/dev/null
+++ b/include/vnd_tetra.txt
@@ -0,0 +1,15 @@
+BT_WAKE_VIA_USERIAL_IOCTL = TRUE
+BT_WAKE_USERIAL_LDISC = TRUE
+LPM_BT_WAKE_POLARITY = 0
+LPM_HOST_WAKE_POLARITY = 0
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+LPM_IDLE_THRESHOLD = 1
+LPM_HC_IDLE_THRESHOLD = 1
+SCO_I2SPCM_IF_ROLE = 0
+SCO_I2SPCM_IF_CLOCK_RATE = 0
+SCO_PCM_IF_CLOCK_RATE = 0
+SCO_I2SPCM_IF_CLOCK_RATE4WBS = 1
+BTVND_DBG = FALSE
+BTHW_DBG = FALSE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_tilapia.txt b/include/vnd_tilapia.txt
new file mode 100644
index 0000000..3e4d71c
--- a/dev/null
+++ b/include/vnd_tilapia.txt
@@ -0,0 +1,10 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2"
+FW_PATCHFILE_LOCATION = "/etc/firmware/"
+BT_WAKE_VIA_PROC = TRUE
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+SCO_PCM_IF_CLOCK_RATE = 2
+USE_CONTROLLER_BDADDR = TRUE
diff --git a/include/vnd_toro.txt b/include/vnd_toro.txt
new file mode 100644
index 0000000..43e790c
--- a/dev/null
+++ b/include/vnd_toro.txt
@@ -0,0 +1,9 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_USERIAL_IOCTL = TRUE
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = TRUE
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_tuna.txt b/include/vnd_tuna.txt
new file mode 100644
index 0000000..43e790c
--- a/dev/null
+++ b/include/vnd_tuna.txt
@@ -0,0 +1,9 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyO1"
+FW_PATCHFILE_LOCATION = "/vendor/firmware/"
+BT_WAKE_VIA_USERIAL_IOCTL = TRUE
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+SCO_USE_I2S_INTERFACE = TRUE
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
diff --git a/include/vnd_wingray.txt b/include/vnd_wingray.txt
new file mode 100644
index 0000000..f5eb1d0
--- a/dev/null
+++ b/include/vnd_wingray.txt
@@ -0,0 +1,8 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS2"
+FW_PATCHFILE_LOCATION = "/etc/firmware/"
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+SCO_PCM_IF_CLOCK_RATE = 2
diff --git a/include/vnd_wren.txt b/include/vnd_wren.txt
new file mode 100644
index 0000000..db52a83
--- a/dev/null
+++ b/include/vnd_wren.txt
@@ -0,0 +1,10 @@
+BLUETOOTH_UART_DEVICE_PORT = "/dev/ttyHS0"
+FW_PATCHFILE_LOCATION = "/system/etc/firmware/bt"
+UART_TARGET_BAUD_RATE = 3000000
+LPM_IDLE_TIMEOUT_MULTIPLE = 5
+BTVND_DBG = FALSE
+BTHW_DBG = TRUE
+VNDUSERIAL_DBG = FALSE
+UPIO_DBG = FALSE
+BT_WAKE_VIA_PROC = TRUE
+PROC_BTWRITE_TIMER_TIMEOUT_MS = 0
diff --git a/src/bt_vendor_brcm.c b/src/bt_vendor_brcm.c
index 9bd8922..05a5bcb 100755
--- a/src/bt_vendor_brcm.c
+++ b/src/bt_vendor_brcm.c
@@ -27,6 +27,7 @@
#define LOG_TAG "bt_vendor"
#include <utils/Log.h>
+#include <string.h>
#include "bt_vendor_brcm.h"
#include "upio.h"
#include "userial_vendor.h"
@@ -53,6 +54,9 @@ void hw_lpm_set_wake_state(uint8_t wake_assert);
void hw_sco_config(void);
#endif
void vnd_load_conf(const char *p_path);
+#if (HW_END_WITH_HCI_RESET == TRUE)
+void hw_epilog_process(void);
+#endif
/******************************************************************************
** Variables
@@ -203,6 +207,25 @@ static int op(bt_vendor_opcode_t opcode, void *param)
hw_lpm_set_wake_state(wake_assert);
}
break;
+
+ case BT_VND_OP_SET_AUDIO_STATE:
+ {
+ retval = hw_set_audio_state((bt_vendor_op_audio_state_t *)param);
+ }
+ break;
+
+ case BT_VND_OP_EPILOG:
+ {
+#if (HW_END_WITH_HCI_RESET == FALSE)
+ if (bt_vendor_cbacks)
+ {
+ bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
+ }
+#else
+ hw_epilog_process();
+#endif
+ }
+ break;
}
return retval;
diff --git a/src/hardware.c b/src/hardware.c
index 180325c..02103ca 100755
--- a/src/hardware.c
+++ b/src/hardware.c
@@ -39,8 +39,10 @@
#include <ctype.h>
#include <cutils/properties.h>
#include <stdlib.h>
+#include <string.h>
#include "bt_hci_bdroid.h"
#include "bt_vendor_brcm.h"
+#include "hci_audio.h"
#include "userial.h"
#include "userial_vendor.h"
#include "upio.h"
@@ -48,6 +50,7 @@
/******************************************************************************
** Constants & Macros
******************************************************************************/
+
#ifndef BTHW_DBG
#define BTHW_DBG FALSE
#endif
@@ -75,6 +78,7 @@
#define HCI_VSC_WRITE_SCO_PCM_INT_PARAM 0xFC1C
#define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM 0xFC1E
#define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM 0xFC6D
+#define HCI_VSC_ENABLE_WBS 0xFC7E
#define HCI_VSC_LAUNCH_RAM 0xFC4E
#define HCI_READ_LOCAL_BDADDR 0x1009
@@ -91,9 +95,17 @@
#define LOCAL_BDADDR_PATH_BUFFER_LEN 256
#define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
+#define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);}
#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
#define UINT32_TO_STREAM(p, u32) {*(p)++ = (uint8_t)(u32); *(p)++ = (uint8_t)((u32) >> 8); *(p)++ = (uint8_t)((u32) >> 16); *(p)++ = (uint8_t)((u32) >> 24);}
+#define SCO_INTERFACE_PCM 0
+#define SCO_INTERFACE_I2S 1
+
+/* one byte is for enable/disable
+ next 2 bytes are for codec type */
+#define SCO_CODEC_PARAM_SIZE 3
+
/******************************************************************************
** Local type definitions
******************************************************************************/
@@ -159,11 +171,12 @@ extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN];
******************************************************************************/
static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION;
-static char fw_patchfile_name[128] = {0};
+static char fw_patchfile_name[128] = { 0 };
#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
static int fw_patch_settlement_delay = -1;
#endif
+static int wbs_sample_rate = SCO_WBS_SAMPLE_RATE;
static bt_hw_cfg_cb_t hw_cfg_cb;
static bt_lpm_param_t lpm_param =
@@ -182,7 +195,9 @@ static bt_lpm_param_t lpm_param =
LPM_PULSED_HOST_WAKE
};
-#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
+/* need to update the bt_sco_i2spcm_param as well
+ bt_sco_i2spcm_param will be used for WBS setting
+ update the bt_sco_param and bt_sco_i2spcm_param */
static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] =
{
SCO_PCM_ROUTING,
@@ -200,15 +215,14 @@ static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] =
PCM_DATA_FMT_FILL_NUM,
PCM_DATA_FMT_JUSTIFY_MODE
};
-#else
-static uint8_t bt_sco_param[SCO_I2SPCM_PARAM_SIZE] =
+
+static uint8_t bt_sco_i2spcm_param[SCO_I2SPCM_PARAM_SIZE] =
{
SCO_I2SPCM_IF_MODE,
SCO_I2SPCM_IF_ROLE,
SCO_I2SPCM_IF_SAMPLE_RATE,
SCO_I2SPCM_IF_CLOCK_RATE
};
-#endif
/*
* The look-up table of recommended firmware settlement delay (milliseconds) on
@@ -216,12 +230,34 @@ static uint8_t bt_sco_param[SCO_I2SPCM_PARAM_SIZE] =
*/
static const fw_settlement_entry_t fw_settlement_table[] = {
{"BCM43241", 200},
+ {"BCM43341", 100},
{(const char *) NULL, 100} // Giving the generic fw settlement delay setting.
};
+
+/*
+ * NOTICE:
+ * If the platform plans to run I2S interface bus over I2S/PCM port of the
+ * BT Controller with the Host AP, explicitly set "SCO_USE_I2S_INTERFACE = TRUE"
+ * in the correspodning include/vnd_<target>.txt file.
+ * Otherwise, leave SCO_USE_I2S_INTERFACE undefined in the vnd_<target>.txt file.
+ * And, PCM interface will be set as the default bus format running over I2S/PCM
+ * port.
+ */
+#if (defined(SCO_USE_I2S_INTERFACE) && SCO_USE_I2S_INTERFACE == TRUE)
+static uint8_t sco_bus_interface = SCO_INTERFACE_I2S;
+#else
+static uint8_t sco_bus_interface = SCO_INTERFACE_PCM;
+#endif
+
+#define INVALID_SCO_CLOCK_RATE 0xFF
+static uint8_t sco_bus_clock_rate = INVALID_SCO_CLOCK_RATE;
+static uint8_t sco_bus_wbs_clock_rate = INVALID_SCO_CLOCK_RATE;
+
/******************************************************************************
** Static functions
******************************************************************************/
+static void hw_sco_i2spcm_config(void *p_mem, uint16_t codec);
/******************************************************************************
** Controller Initialization Static Functions
@@ -585,6 +621,7 @@ void hw_config_cback(void *p_mem)
HC_BT_HDR *p_buf=NULL;
uint8_t is_proceeding = FALSE;
int i;
+ int delay=100;
#if (USE_CONTROLLER_BDADDR == TRUE)
const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
#endif
@@ -622,13 +659,12 @@ void hw_config_cback(void *p_mem)
p_buf->len = HCI_CMD_PREAMBLE_SIZE;
hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME;
- ms_delay(10);
+
is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \
p_buf, hw_config_cback);
break;
case HW_CFG_READ_LOCAL_NAME:
- ALOGI("bt vendor lib: read local name");
p_tmp = p_name = (char *) (p_evt_buf + 1) + \
HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING;
@@ -665,7 +701,6 @@ void hw_config_cback(void *p_mem)
p_buf->len = HCI_CMD_PREAMBLE_SIZE;
hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER;
- ms_delay(50);
is_proceeding = bt_vendor_cbacks->xmit_cb( \
HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \
@@ -686,13 +721,11 @@ void hw_config_cback(void *p_mem)
break;
case HW_CFG_DL_MINIDRIVER:
- ALOGI("bt vendor lib: download minidriver");
/* give time for placing firmware in download mode */
- ms_delay(100);
+ ms_delay(50);
hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
/* fall through intentionally */
case HW_CFG_DL_FW_PATCH:
- //ALOGI("bt vendor lib: download fw");
p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE);
if (p_buf->len > 0)
{
@@ -731,9 +764,17 @@ void hw_config_cback(void *p_mem)
/* Check if we need to pause a few hundred milliseconds
* before sending down any HCI command.
*/
- ms_delay(look_up_fw_settlement_delay());
+ delay = look_up_fw_settlement_delay();
+ ALOGI("Setting fw settlement delay to %d ", delay);
+ ms_delay(delay);
+
+ p_buf->len = HCI_CMD_PREAMBLE_SIZE;
+ UINT16_TO_STREAM(p, HCI_RESET);
+ *p = 0; /* parameter length */
+ hw_cfg_cb.state = HW_CFG_START;
+ is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback);
+ break;
- /* fall through intentionally */
case HW_CFG_START:
if (UART_TARGET_BAUD_RATE > 3000000)
{
@@ -774,7 +815,7 @@ void hw_config_cback(void *p_mem)
userial_vendor_set_baud( \
line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
);
- ms_delay(10);
+
#if (USE_CONTROLLER_BDADDR == TRUE)
if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE)
break;
@@ -899,63 +940,146 @@ void hw_lpm_ctrl_cback(void *p_mem)
/*******************************************************************************
**
-** Function hw_sco_cfg_cback
+** Function hw_sco_i2spcm_cfg_cback
**
-** Description Callback function for SCO configuration rquest
+** Description Callback function for SCO I2S/PCM configuration rquest
**
** Returns None
**
*******************************************************************************/
-void hw_sco_cfg_cback(void *p_mem)
+static void hw_sco_i2spcm_cfg_cback(void *p_mem)
{
- HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
+ HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
uint8_t *p;
uint16_t opcode;
- HC_BT_HDR *p_buf=NULL;
+ HC_BT_HDR *p_buf = NULL;
+ bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL;
p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
STREAM_TO_UINT16(opcode,p);
+ if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0)
+ {
+ status = BT_VND_OP_RESULT_SUCCESS;
+ }
+
/* Free the RX event buffer */
if (bt_vendor_cbacks)
bt_vendor_cbacks->dealloc(p_evt_buf);
-#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
- if (opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM)
+ if (status == BT_VND_OP_RESULT_SUCCESS)
{
- uint8_t ret = FALSE;
-
- /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */
- if (bt_vendor_cbacks)
- p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
- HCI_CMD_PREAMBLE_SIZE + \
- PCM_DATA_FORMAT_PARAM_SIZE);
- if (p_buf)
+ if ((opcode == HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM) &&
+ (SCO_INTERFACE_PCM == sco_bus_interface))
{
- p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
- p_buf->offset = 0;
- p_buf->layer_specific = 0;
- p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE;
+ uint8_t ret = FALSE;
- p = (uint8_t *) (p_buf + 1);
- UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM);
- *p++ = PCM_DATA_FORMAT_PARAM_SIZE;
- memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE);
+ /* Ask a new buffer to hold WRITE_SCO_PCM_INT_PARAM command */
+ if (bt_vendor_cbacks)
+ p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
+ BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE);
+ if (p_buf)
+ {
+ p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE;
+ p = (uint8_t *)(p_buf + 1);
+
+ /* do we need this VSC for I2S??? */
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM);
+ *p++ = SCO_PCM_PARAM_SIZE;
+ memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE);
+ ALOGI("SCO PCM configure {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}",
+ bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3],
+ bt_sco_param[4]);
+ if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SCO_PCM_INT_PARAM, p_buf,
+ hw_sco_i2spcm_cfg_cback)) == FALSE)
+ {
+ bt_vendor_cbacks->dealloc(p_buf);
+ }
+ else
+ return;
+ }
+ status = BT_VND_OP_RESULT_FAIL;
+ }
+ else if ((opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM) &&
+ (SCO_INTERFACE_PCM == sco_bus_interface))
+ {
+ uint8_t ret = FALSE;
- if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,\
- p_buf, hw_sco_cfg_cback)) == FALSE)
+ /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */
+ if (bt_vendor_cbacks)
+ p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
+ BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE);
+ if (p_buf)
{
- bt_vendor_cbacks->dealloc(p_buf);
+ p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE;
+
+ p = (uint8_t *)(p_buf + 1);
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM);
+ *p++ = PCM_DATA_FORMAT_PARAM_SIZE;
+ memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE);
+
+ ALOGI("SCO PCM data format {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}",
+ bt_pcm_data_fmt_param[0], bt_pcm_data_fmt_param[1],
+ bt_pcm_data_fmt_param[2], bt_pcm_data_fmt_param[3],
+ bt_pcm_data_fmt_param[4]);
+
+ if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,
+ p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE)
+ {
+ bt_vendor_cbacks->dealloc(p_buf);
+ }
+ else
+ return;
}
- else
- return;
+ status = BT_VND_OP_RESULT_FAIL;
}
}
-#endif // !SCO_USE_I2S_INTERFACE
-if (bt_vendor_cbacks)
- bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
+ ALOGI("sco I2S/PCM config result %d [0-Success, 1-Fail]", status);
+ if (bt_vendor_cbacks)
+ {
+ bt_vendor_cbacks->audio_state_cb(status);
+ }
}
+
+/*******************************************************************************
+**
+** Function hw_set_MSBC_codec_cback
+**
+** Description Callback function for setting WBS codec
+**
+** Returns None
+**
+*******************************************************************************/
+static void hw_set_MSBC_codec_cback(void *p_mem)
+{
+ /* whenever update the codec enable/disable, need to update I2SPCM */
+ ALOGI("SCO I2S interface change the sample rate to 16K");
+ hw_sco_i2spcm_config(p_mem, SCO_CODEC_MSBC);
+}
+
+/*******************************************************************************
+**
+** Function hw_set_CVSD_codec_cback
+**
+** Description Callback function for setting NBS codec
+**
+** Returns None
+**
+*******************************************************************************/
+static void hw_set_CVSD_codec_cback(void *p_mem)
+{
+ /* whenever update the codec enable/disable, need to update I2SPCM */
+ ALOGI("SCO I2S interface change the sample rate to 8K");
+ hw_sco_i2spcm_config(p_mem, SCO_CODEC_CVSD);
+}
+
#endif // SCO_CFG_INCLUDED
/*****************************************************************************
@@ -1124,63 +1248,236 @@ void hw_lpm_set_wake_state(uint8_t wake_assert)
*******************************************************************************/
void hw_sco_config(void)
{
- HC_BT_HDR *p_buf = NULL;
- uint8_t *p, ret;
+ if (SCO_INTERFACE_I2S == sco_bus_interface)
+ {
+ /* 'Enable' I2S mode */
+ bt_sco_i2spcm_param[0] = 1;
-#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
- uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE;
-#else
- uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
-#endif
+ /* set nbs clock rate as the value in SCO_I2SPCM_IF_CLOCK_RATE field */
+ sco_bus_clock_rate = bt_sco_i2spcm_param[3];
+ }
+ else
+ {
+ /* 'Disable' I2S mode */
+ bt_sco_i2spcm_param[0] = 0;
+
+ /* set nbs clock rate as the value in SCO_PCM_IF_CLOCK_RATE field */
+ sco_bus_clock_rate = bt_sco_param[1];
+
+ /* sync up clock mode setting */
+ bt_sco_i2spcm_param[1] = bt_sco_param[4];
+ }
+
+ if (sco_bus_wbs_clock_rate == INVALID_SCO_CLOCK_RATE)
+ {
+ /* set default wbs clock rate */
+ sco_bus_wbs_clock_rate = SCO_I2SPCM_IF_CLOCK_RATE4WBS;
+
+ if (sco_bus_wbs_clock_rate < sco_bus_clock_rate)
+ sco_bus_wbs_clock_rate = sco_bus_clock_rate;
+ }
+
+ /*
+ * To support I2S/PCM port multiplexing signals for sharing Bluetooth audio
+ * and FM on the same PCM pins, we defer Bluetooth audio (SCO/eSCO)
+ * configuration till SCO/eSCO is being established;
+ * i.e. in hw_set_audio_state() call.
+ */
+
+ if (bt_vendor_cbacks)
+ {
+ bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
+ }
+}
+
+/*******************************************************************************
+**
+** Function hw_sco_i2spcm_config
+**
+** Description Configure SCO over I2S or PCM
+**
+** Returns None
+**
+*******************************************************************************/
+static void hw_sco_i2spcm_config(void *p_mem, uint16_t codec)
+{
+ HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
+ bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL;
+
+ if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0)
+ {
+ status = BT_VND_OP_RESULT_SUCCESS;
+ }
+
+ /* Free the RX event buffer */
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->dealloc(p_evt_buf);
+
+ if (status == BT_VND_OP_RESULT_SUCCESS)
+ {
+ HC_BT_HDR *p_buf = NULL;
+ uint8_t *p, ret;
+ uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
+
+ if (bt_vendor_cbacks)
+ p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + cmd_u16);
+
+ if (p_buf)
+ {
+ p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = cmd_u16;
+
+ p = (uint8_t *)(p_buf + 1);
+
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
+ *p++ = SCO_I2SPCM_PARAM_SIZE;
+ if (codec == SCO_CODEC_CVSD)
+ {
+ bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */
+ bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
+ }
+ else if (codec == SCO_CODEC_MSBC)
+ {
+ bt_sco_i2spcm_param[2] = wbs_sample_rate; /* SCO_I2SPCM_IF_SAMPLE_RATE 16K */
+ bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_wbs_clock_rate;
+ }
+ else
+ {
+ bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */
+ bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
+ ALOGE("wrong codec is use in hw_sco_i2spcm_config, goes default NBS");
+ }
+ memcpy(p, &bt_sco_i2spcm_param, SCO_I2SPCM_PARAM_SIZE);
+ cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
+ ALOGI("I2SPCM config {0x%x, 0x%x, 0x%x, 0x%x}",
+ bt_sco_i2spcm_param[0], bt_sco_i2spcm_param[1],
+ bt_sco_i2spcm_param[2], bt_sco_i2spcm_param[3]);
+
+ if ((ret = bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE)
+ {
+ bt_vendor_cbacks->dealloc(p_buf);
+ }
+ else
+ return;
+ }
+ status = BT_VND_OP_RESULT_FAIL;
+ }
+
+ if (bt_vendor_cbacks)
+ {
+ bt_vendor_cbacks->audio_state_cb(status);
+ }
+}
+
+/*******************************************************************************
+**
+** Function hw_set_SCO_codec
+**
+** Description This functgion sends command to the controller to setup
+** WBS/NBS codec for the upcoming eSCO connection.
+**
+** Returns -1 : Failed to send VSC
+** 0 : Success
+**
+*******************************************************************************/
+static int hw_set_SCO_codec(uint16_t codec)
+{
+ HC_BT_HDR *p_buf = NULL;
+ uint8_t *p;
+ uint8_t ret;
+ int ret_val = 0;
+ tINT_CMD_CBACK p_set_SCO_codec_cback;
+
+ BTHWDBG( "hw_set_SCO_codec 0x%x", codec);
if (bt_vendor_cbacks)
- p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE+cmd_u16);
+ p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
+ BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE);
if (p_buf)
{
p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
p_buf->offset = 0;
p_buf->layer_specific = 0;
- p_buf->len = cmd_u16;
+ p = (uint8_t *)(p_buf + 1);
- p = (uint8_t *) (p_buf + 1);
-#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
- UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM);
- *p++ = SCO_PCM_PARAM_SIZE;
- memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE);
- cmd_u16 = HCI_VSC_WRITE_SCO_PCM_INT_PARAM;
- ALOGI("SCO PCM configure {%d, %d, %d, %d, %d}",
- bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3], \
- bt_sco_param[4]);
+ UINT16_TO_STREAM(p, HCI_VSC_ENABLE_WBS);
-#else
- UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
- *p++ = SCO_I2SPCM_PARAM_SIZE;
- memcpy(p, &bt_sco_param, SCO_I2SPCM_PARAM_SIZE);
- cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
- ALOGI("SCO over I2SPCM interface {%d, %d, %d, %d}",
- bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3]);
-#endif
+ if (codec == SCO_CODEC_MSBC)
+ {
+ /* Enable mSBC */
+ *p++ = SCO_CODEC_PARAM_SIZE; /* set the parameter size */
+ UINT8_TO_STREAM(p,1); /* enable */
+ UINT16_TO_STREAM(p, codec);
- if ((ret=bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_cfg_cback)) \
- == FALSE)
+ /* set the totall size of this packet */
+ p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE;
+
+ p_set_SCO_codec_cback = hw_set_MSBC_codec_cback;
+ }
+ else
+ {
+ /* Disable mSBC */
+ *p++ = (SCO_CODEC_PARAM_SIZE - 2); /* set the parameter size */
+ UINT8_TO_STREAM(p,0); /* disable */
+
+ /* set the totall size of this packet */
+ p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE - 2;
+
+ p_set_SCO_codec_cback = hw_set_CVSD_codec_cback;
+ if ((codec != SCO_CODEC_CVSD) && (codec != SCO_CODEC_NONE))
+ {
+ ALOGW("SCO codec setting is wrong: codec: 0x%x", codec);
+ }
+ }
+
+ if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_ENABLE_WBS, p_buf, p_set_SCO_codec_cback))\
+ == FALSE)
{
bt_vendor_cbacks->dealloc(p_buf);
+ ret_val = -1;
}
- else
- return;
}
-
- if (bt_vendor_cbacks)
+ else
{
- ALOGE("vendor lib scocfg aborted");
- bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_FAIL);
+ ret_val = -1;
}
+
+ return ret_val;
}
-#endif // SCO_CFG_INCLUDED
/*******************************************************************************
**
+** Function hw_set_audio_state
+**
+** Description This function configures audio base on provided audio state
+**
+** Paramters pointer to audio state structure
+**
+** Returns 0: ok, -1: error
+**
+*******************************************************************************/
+int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state)
+{
+ int ret_val = -1;
+
+ if (!bt_vendor_cbacks)
+ return ret_val;
+
+ ret_val = hw_set_SCO_codec(p_state->peer_codec);
+ return ret_val;
+}
+
+#else // SCO_CFG_INCLUDED
+int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state)
+{
+ return -256;
+}
+#endif
+/*******************************************************************************
+**
** Function hw_set_patch_file_path
**
** Description Set the location of firmware patch file
@@ -1234,3 +1531,89 @@ int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int par
}
#endif //VENDOR_LIB_RUNTIME_TUNING_ENABLED
+/*****************************************************************************
+** Sample Codes Section
+*****************************************************************************/
+
+#if (HW_END_WITH_HCI_RESET == TRUE)
+/*******************************************************************************
+**
+** Function hw_epilog_cback
+**
+** Description Callback function for Command Complete Events from HCI
+** commands sent in epilog process.
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_epilog_cback(void *p_mem)
+{
+ HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
+ uint8_t *p, status;
+ uint16_t opcode;
+
+ status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
+ p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
+ STREAM_TO_UINT16(opcode,p);
+
+ BTHWDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status);
+
+ if (bt_vendor_cbacks)
+ {
+ /* Must free the RX event buffer */
+ bt_vendor_cbacks->dealloc(p_evt_buf);
+
+ /* Once epilog process is done, must call epilog_cb callback
+ to notify caller */
+ bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
+ }
+}
+
+/*******************************************************************************
+**
+** Function hw_epilog_process
+**
+** Description Sample implementation of epilog process
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_epilog_process(void)
+{
+ HC_BT_HDR *p_buf = NULL;
+ uint8_t *p;
+
+ BTHWDBG("hw_epilog_process");
+
+ /* Sending a HCI_RESET */
+ if (bt_vendor_cbacks)
+ {
+ /* Must allocate command buffer via HC's alloc API */
+ p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
+ HCI_CMD_PREAMBLE_SIZE);
+ }
+
+ if (p_buf)
+ {
+ p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = HCI_CMD_PREAMBLE_SIZE;
+
+ p = (uint8_t *) (p_buf + 1);
+ UINT16_TO_STREAM(p, HCI_RESET);
+ *p = 0; /* parameter length */
+
+ /* Send command via HC's xmit_cb API */
+ bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback);
+ }
+ else
+ {
+ if (bt_vendor_cbacks)
+ {
+ ALOGE("vendor lib epilog process aborted [no buffer]");
+ bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL);
+ }
+ }
+}
+#endif // (HW_END_WITH_HCI_RESET == TRUE)
diff --git a/src/upio.c b/src/upio.c
index 4940f8e..3f73482 100755
--- a/src/upio.c
+++ b/src/upio.c
@@ -31,6 +31,7 @@
#include <utils/Log.h>
#include <fcntl.h>
#include <errno.h>
+#include <string.h>
#include <cutils/properties.h>
#include "bt_vendor_brcm.h"
#include "upio.h"
@@ -194,6 +195,40 @@ static void proc_btwrite_timeout(union sigval arg)
{
UPIODBG("..%s..", __FUNCTION__);
lpm_proc_cb.btwrite_active = FALSE;
+ /* drive LPM down; this timer should fire only when BT is awake; */
+ upio_set(UPIO_BT_WAKE, UPIO_DEASSERT, 1);
+}
+
+/******************************************************************************
+ **
+ ** Function upio_start_stop_timer
+ **
+ ** Description Arm user space timer in case lpm is left asserted
+ **
+ ** Returns None
+ **
+ *****************************************************************************/
+void upio_start_stop_timer(int action) {
+ struct itimerspec ts;
+
+ if (action == UPIO_ASSERT) {
+ lpm_proc_cb.btwrite_active = TRUE;
+ if (lpm_proc_cb.timer_created == TRUE) {
+ ts.it_value.tv_sec = PROC_BTWRITE_TIMER_TIMEOUT_MS/1000;
+ ts.it_value.tv_nsec = 1000000*(PROC_BTWRITE_TIMER_TIMEOUT_MS%1000);
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+ }
+ } else {
+ /* unarm timer if writing 0 to lpm; reduce unnecessary user space wakeup */
+ memset(&ts, 0, sizeof(ts));
+ }
+
+ if (timer_settime(lpm_proc_cb.timer_id, 0, &ts, 0) == 0) {
+ UPIODBG("%s : timer_settime success", __FUNCTION__);
+ } else {
+ UPIODBG("%s : timer_settime failed", __FUNCTION__);
+ }
}
#endif
@@ -330,6 +365,8 @@ void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
char buffer;
#endif
+ UPIODBG("%s : pio %d action %d, polarity %d", __FUNCTION__, pio, action, polarity);
+
switch (pio)
{
case UPIO_LPM_MODE:
@@ -353,12 +390,10 @@ void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
if (action == UPIO_ASSERT)
{
- UPIODBG("LPM asserted");
buffer = '1';
}
else
{
- UPIODBG("LPM deasserted");
buffer = '0';
// delete btwrite assertion holding timer
@@ -374,6 +409,7 @@ void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
ALOGE("upio_set : write(%s) failed: %s (%d)",
VENDOR_LPM_PROC_NODE, strerror(errno),errno);
}
+#if (PROC_BTWRITE_TIMER_TIMEOUT_MS != 0)
else
{
if (action == UPIO_ASSERT)
@@ -397,6 +433,7 @@ void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
}
}
}
+#endif
if (fd >= 0)
close(fd);
@@ -404,7 +441,6 @@ void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
break;
case UPIO_BT_WAKE:
-
if (upio_state[UPIO_BT_WAKE] == action)
{
UPIODBG("BT_WAKE is %s already", lpm_state[action]);
@@ -420,22 +456,16 @@ void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
* a 10sec internal in-activity timeout timer before it
* attempts to deassert BT_WAKE line.
*/
-#endif
+ return;
+#else
return;
+#endif
}
upio_state[UPIO_BT_WAKE] = action;
- /****************************************
- * !!! TODO !!!
- *
- * === Custom Porting Required ===
- *
- * Platform dependent user-to-kernel
- * interface is required to set output
- * state of physical BT_WAKE pin.
- ****************************************/
#if (BT_WAKE_VIA_USERIAL_IOCTL == TRUE)
+
userial_vendor_ioctl( ( (action==UPIO_ASSERT) ? \
USERIAL_OP_ASSERT_BT_WAKE : USERIAL_OP_DEASSERT_BT_WAKE),\
NULL);
@@ -445,12 +475,10 @@ void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
/*
* Kick proc btwrite node only at UPIO_ASSERT
*/
+#if (BT_WAKE_VIA_PROC_NOTIFY_DEASSERT == FALSE)
if (action == UPIO_DEASSERT)
- {
- UPIODBG("btwake deassertion");
return;
- }
-
+#endif
fd = open(VENDOR_BTWRITE_PROC_NODE, O_WRONLY);
if (fd < 0)
@@ -459,36 +487,33 @@ void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
VENDOR_BTWRITE_PROC_NODE, strerror(errno), errno);
return;
}
-
- buffer = '1';
+#if (BT_WAKE_VIA_PROC_NOTIFY_DEASSERT == TRUE)
+ if (action == UPIO_DEASSERT)
+ buffer = '0';
+ else
+#endif
+ buffer = '1';
if (write(fd, &buffer, 1) < 0)
{
ALOGE("upio_set : write(%s) failed: %s (%d)",
VENDOR_BTWRITE_PROC_NODE, strerror(errno),errno);
}
+#if (PROC_BTWRITE_TIMER_TIMEOUT_MS != 0)
else
{
- lpm_proc_cb.btwrite_active = TRUE;
-
- if (lpm_proc_cb.timer_created == TRUE)
- {
- struct itimerspec ts;
-
- ts.it_value.tv_sec = PROC_BTWRITE_TIMER_TIMEOUT_MS/1000;
- ts.it_value.tv_nsec = 1000*(PROC_BTWRITE_TIMER_TIMEOUT_MS%1000);
- ts.it_interval.tv_sec = 0;
- ts.it_interval.tv_nsec = 0;
-
- timer_settime(lpm_proc_cb.timer_id, 0, &ts, 0);
- }
+ /* arm user space timer based on action */
+ upio_start_stop_timer(action);
}
- //ms_delay(10);
- UPIODBG("proc btwrite assertion");
+#endif
+
+ UPIODBG("%s: proc btwrite assertion, buffer: %c, timer_armed %d %d",
+ __FUNCTION__, buffer, lpm_proc_cb.btwrite_active, lpm_proc_cb.timer_created);
if (fd >= 0)
close(fd);
#endif
+
break;
case UPIO_HOST_WAKE:
diff --git a/src/userial_vendor.c b/src/userial_vendor.c
index 09bf954..3ff518b 100755
--- a/src/userial_vendor.c
+++ b/src/userial_vendor.c
@@ -31,6 +31,7 @@
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
+#include <string.h>
#include "bt_vendor_brcm.h"
#include "userial.h"
#include "userial_vendor.h"
@@ -51,10 +52,6 @@
#define VND_PORT_NAME_MAXLEN 256
-#if (BT_WAKE_VIA_PROC == TRUE)
-#define TIOCSETBTPORT 0x5489
-#define TIOCCLRBTPORT 0x5490
-#endif
/******************************************************************************
** Local type definitions
******************************************************************************/
@@ -141,6 +138,19 @@ void userial_ioctl_init_bt_wake(int fd)
{
uint32_t bt_wake_state;
+#if (BT_WAKE_USERIAL_LDISC==TRUE)
+ int ldisc = N_BRCM_HCI; /* brcm sleep mode support line discipline */
+
+ /* attempt to load enable discipline driver */
+ if (ioctl(vnd_userial.fd, TIOCSETD, &ldisc) < 0)
+ {
+ VNDUSERIALDBG("USERIAL_Open():fd %d, TIOCSETD failed: error %d for ldisc: %d",
+ fd, errno, ldisc);
+ }
+#endif
+
+
+
/* assert BT_WAKE through ioctl */
ioctl(fd, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL);
ioctl(fd, USERIAL_IOCTL_BT_WAKE_GET_ST, &bt_wake_state);
@@ -257,10 +267,6 @@ int userial_vendor_open(tUSERIAL_CFG *p_cfg)
#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
userial_ioctl_init_bt_wake(vnd_userial.fd);
#endif
-#if (BT_WAKE_VIA_PROC == TRUE)
- /* set bluesleep uart port */
- ioctl(vnd_userial.fd, TIOCSETBTPORT, NULL);
-#endif
ALOGI("device fd = %d open", vnd_userial.fd);
@@ -287,11 +293,10 @@ void userial_vendor_close(void)
/* de-assert bt_wake BEFORE closing port */
ioctl(vnd_userial.fd, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL);
#endif
-#if (BT_WAKE_VIA_PROC == TRUE)
- ioctl(vnd_userial.fd, TIOCCLRBTPORT, NULL);
-#endif
- ALOGI("device fd = %d close", vnd_userial.fd);
+ ALOGI("device fd = %d close", vnd_userial.fd);
+ // flush Tx before close to make sure no chars in buffer
+ tcflush(vnd_userial.fd, TCIOFLUSH);
if ((result = close(vnd_userial.fd)) < 0)
ALOGE( "close(fd:%d) FAILED result:%d", vnd_userial.fd, result);
diff --git a/vnd_buildcfg.mk b/vnd_buildcfg.mk
index 10e2ad1..af1787a 100755
--- a/vnd_buildcfg.mk
+++ b/vnd_buildcfg.mk
@@ -2,17 +2,15 @@ generated_sources := $(local-generated-sources-dir)
ifeq ($(BCM_BLUETOOTH_LPM_ENABLE),true)
SRC := $(call my-dir)/include/$(addprefix vnd_, $(addsuffix _lpm.txt,$(basename $(TARGET_BOARD_PLATFORM))))
-#SRC := $(call my-dir)/include/vnd_40183_lpm.txt
else
SRC := $(call my-dir)/include/$(addprefix vnd_, $(addsuffix .txt,$(basename $(TARGET_BOARD_PLATFORM))))
-#SRC := $(call my-dir)/include/vnd_40183.txt
endif
ifeq (,$(wildcard $(SRC)))
# configuration file does not exist. Use default one
SRC := $(call my-dir)/include/vnd_generic.txt
endif
GEN := $(generated_sources)/vnd_buildcfg.h
-TOOL := $(TOP_DIR)external/bluetooth/bluedroid/tools/gen-buildcfg.sh
+TOOL := $(LOCAL_PATH)/gen-buildcfg.sh
$(GEN): PRIVATE_PATH := $(call my-dir)
$(GEN): PRIVATE_CUSTOM_TOOL = $(TOOL) $< $@