diff options
Diffstat (limited to 'libbt/src/hardware.c')
-rw-r--r-- | libbt/src/hardware.c | 1155 |
1 files changed, 0 insertions, 1155 deletions
diff --git a/libbt/src/hardware.c b/libbt/src/hardware.c deleted file mode 100644 index a6868e1..0000000 --- a/libbt/src/hardware.c +++ /dev/null @@ -1,1155 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2009-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Filename: hardware.c - * - * Description: Contains controller-specific functions, like - * firmware patch download - * low power mode operations - * - ******************************************************************************/ - -#define LOG_TAG "bt_hwcfg" - -#include <utils/Log.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <signal.h> -#include <time.h> -#include <errno.h> -#include <fcntl.h> -#include <dirent.h> -#include <ctype.h> -#include <cutils/properties.h> -#include <stdlib.h> -#include "bt_hci_bdroid.h" -#include "bt_vendor_brcm.h" -#include "userial.h" -#include "userial_vendor.h" -#include "upio.h" - -/****************************************************************************** -** Constants & Macros -******************************************************************************/ - -#ifndef BTHW_DBG -#define BTHW_DBG FALSE -#endif - -#if (BTHW_DBG == TRUE) -#define BTHWDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} -#else -#define BTHWDBG(param, ...) {} -#endif - -#define FW_PATCHFILE_EXTENSION ".hcd" -#define FW_PATCHFILE_EXTENSION_LEN 4 -#define FW_PATCHFILE_PATH_MAXLEN 248 /* Local_Name length of return of - HCI_Read_Local_Name */ - -#define HCI_CMD_MAX_LEN 258 - -#define HCI_RESET 0x0C03 -#define HCI_VSC_WRITE_UART_CLOCK_SETTING 0xFC45 -#define HCI_VSC_UPDATE_BAUDRATE 0xFC18 -#define HCI_READ_LOCAL_NAME 0x0C14 -#define HCI_VSC_DOWNLOAD_MINIDRV 0xFC2E -#define HCI_VSC_WRITE_BD_ADDR 0xFC01 -#define HCI_VSC_WRITE_SLEEP_MODE 0xFC27 -#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_LAUNCH_RAM 0xFC4E - -#define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE 5 -#define HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING 6 -#define HCI_EVT_CMD_CMPL_OPCODE 3 -#define LPM_CMD_PARAM_SIZE 12 -#define UPDATE_BAUDRATE_CMD_PARAM_SIZE 6 -#define HCI_CMD_PREAMBLE_SIZE 3 -#define HCD_REC_PAYLOAD_LEN_BYTE 2 -#define BD_ADDR_LEN 6 -#define LOCAL_NAME_BUFFER_LEN 32 -#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 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);} - -/****************************************************************************** -** Local type definitions -******************************************************************************/ - -/* Hardware Configuration State */ -enum { - HW_CFG_START = 1, - HW_CFG_SET_UART_CLOCK, - HW_CFG_SET_UART_BAUD_1, - HW_CFG_READ_LOCAL_NAME, - HW_CFG_DL_MINIDRIVER, - HW_CFG_DL_FW_PATCH, - HW_CFG_SET_UART_BAUD_2, - HW_CFG_SET_BD_ADDR -}; - -/* h/w config control block */ -typedef struct -{ - uint8_t state; /* Hardware configuration state */ - int fw_fd; /* FW patch file fd */ - uint8_t f_set_baud_2; /* Baud rate switch state */ - char local_chip_name[LOCAL_NAME_BUFFER_LEN]; -} bt_hw_cfg_cb_t; - -/* low power mode parameters */ -typedef struct -{ - uint8_t sleep_mode; /* 0(disable),1(UART),9(H5) */ - uint8_t host_stack_idle_threshold; /* Unit scale 300ms/25ms */ - uint8_t host_controller_idle_threshold; /* Unit scale 300ms/25ms */ - uint8_t bt_wake_polarity; /* 0=Active Low, 1= Active High */ - uint8_t host_wake_polarity; /* 0=Active Low, 1= Active High */ - uint8_t allow_host_sleep_during_sco; - uint8_t combine_sleep_mode_and_lpm; - uint8_t enable_uart_txd_tri_state; /* UART_TXD Tri-State */ - uint8_t sleep_guard_time; /* sleep guard time in 12.5ms */ - uint8_t wakeup_guard_time; /* wakeup guard time in 12.5ms */ - uint8_t txd_config; /* TXD is high in sleep state */ - uint8_t pulsed_host_wake; /* pulsed host wake if mode = 1 */ -} bt_lpm_param_t; - -/* Firmware re-launch settlement time */ -typedef struct { - const char *chipset_name; - const uint32_t delay_time; -} fw_settlement_entry_t; - - -/****************************************************************************** -** Externs -******************************************************************************/ - -void hw_config_cback(void *p_evt_buf); -extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN]; - - -/****************************************************************************** -** Static variables -******************************************************************************/ - -static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION; -static char fw_patchfile_name[128] = { 0 }; -#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) -static int fw_patch_settlement_delay = -1; -#endif - -static bt_hw_cfg_cb_t hw_cfg_cb; - -static bt_lpm_param_t lpm_param = -{ - LPM_SLEEP_MODE, - LPM_IDLE_THRESHOLD, - LPM_HC_IDLE_THRESHOLD, - LPM_BT_WAKE_POLARITY, - LPM_HOST_WAKE_POLARITY, - LPM_ALLOW_HOST_SLEEP_DURING_SCO, - LPM_COMBINE_SLEEP_MODE_AND_LPM, - LPM_ENABLE_UART_TXD_TRI_STATE, - 0, /* not applicable */ - 0, /* not applicable */ - 0, /* not applicable */ - LPM_PULSED_HOST_WAKE -}; - -#if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE)) -static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] = -{ - SCO_PCM_ROUTING, - SCO_PCM_IF_CLOCK_RATE, - SCO_PCM_IF_FRAME_TYPE, - SCO_PCM_IF_SYNC_MODE, - SCO_PCM_IF_CLOCK_MODE -}; - -static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] = -{ - PCM_DATA_FMT_SHIFT_MODE, - PCM_DATA_FMT_FILL_BITS, - PCM_DATA_FMT_FILL_METHOD, - PCM_DATA_FMT_FILL_NUM, - PCM_DATA_FMT_JUSTIFY_MODE -}; -#else -static uint8_t bt_sco_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 - * known chipsets. - */ -static const fw_settlement_entry_t fw_settlement_table[] = { - {"BCM43241", 200}, - {(const char *) NULL, 100} // Giving the generic fw settlement delay setting. -}; - -/****************************************************************************** -** Static functions -******************************************************************************/ - -/****************************************************************************** -** Controller Initialization Static Functions -******************************************************************************/ - -/******************************************************************************* -** -** Function look_up_fw_settlement_delay -** -** Description If FW_PATCH_SETTLEMENT_DELAY_MS has not been explicitly -** re-defined in the platform specific build-time configuration -** file, we will search into the look-up table for a -** recommended firmware settlement delay value. -** -** Although the settlement time might be also related to board -** configurations such as the crystal clocking speed. -** -** Returns Firmware settlement delay -** -*******************************************************************************/ -uint32_t look_up_fw_settlement_delay (void) -{ - uint32_t ret_value; - fw_settlement_entry_t *p_entry; - - if (FW_PATCH_SETTLEMENT_DELAY_MS > 0) - { - ret_value = FW_PATCH_SETTLEMENT_DELAY_MS; - } -#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) - else if (fw_patch_settlement_delay >= 0) - { - ret_value = fw_patch_settlement_delay; - } -#endif - else - { - p_entry = (fw_settlement_entry_t *)fw_settlement_table; - - while (p_entry->chipset_name != NULL) - { - if (strstr(hw_cfg_cb.local_chip_name, p_entry->chipset_name)!=NULL) - { - break; - } - - p_entry++; - } - - ret_value = p_entry->delay_time; - } - - BTHWDBG( "Settlement delay -- %d ms", ret_value); - - return (ret_value); -} - -/******************************************************************************* -** -** Function ms_delay -** -** Description sleep unconditionally for timeout milliseconds -** -** Returns None -** -*******************************************************************************/ -void ms_delay (uint32_t timeout) -{ - struct timespec delay; - int err; - - if (timeout == 0) - return; - - delay.tv_sec = timeout / 1000; - delay.tv_nsec = 1000 * 1000 * (timeout%1000); - - /* [u]sleep can't be used because it uses SIGALRM */ - do { - err = nanosleep(&delay, &delay); - } while (err < 0 && errno ==EINTR); -} - -/******************************************************************************* -** -** Function line_speed_to_userial_baud -** -** Description helper function converts line speed number into USERIAL baud -** rate symbol -** -** Returns unit8_t (USERIAL baud symbol) -** -*******************************************************************************/ -uint8_t line_speed_to_userial_baud(uint32_t line_speed) -{ - uint8_t baud; - - if (line_speed == 4000000) - baud = USERIAL_BAUD_4M; - else if (line_speed == 3000000) - baud = USERIAL_BAUD_3M; - else if (line_speed == 2000000) - baud = USERIAL_BAUD_2M; - else if (line_speed == 1000000) - baud = USERIAL_BAUD_1M; - else if (line_speed == 921600) - baud = USERIAL_BAUD_921600; - else if (line_speed == 460800) - baud = USERIAL_BAUD_460800; - else if (line_speed == 230400) - baud = USERIAL_BAUD_230400; - else if (line_speed == 115200) - baud = USERIAL_BAUD_115200; - else if (line_speed == 57600) - baud = USERIAL_BAUD_57600; - else if (line_speed == 19200) - baud = USERIAL_BAUD_19200; - else if (line_speed == 9600) - baud = USERIAL_BAUD_9600; - else if (line_speed == 1200) - baud = USERIAL_BAUD_1200; - else if (line_speed == 600) - baud = USERIAL_BAUD_600; - else - { - ALOGE( "userial vendor: unsupported baud speed %d", line_speed); - baud = USERIAL_BAUD_115200; - } - - return baud; -} - - -/******************************************************************************* -** -** Function hw_strncmp -** -** Description Used to compare two strings in caseless -** -** Returns 0: match, otherwise: not match -** -*******************************************************************************/ -static int hw_strncmp (const char *p_str1, const char *p_str2, const int len) -{ - int i; - - if (!p_str1 || !p_str2) - return (1); - - for (i = 0; i < len; i++) - { - if (toupper(p_str1[i]) != toupper(p_str2[i])) - return (i+1); - } - - return 0; -} - -/******************************************************************************* -** -** Function hw_config_findpatch -** -** Description Search for a proper firmware patch file -** The selected firmware patch file name with full path -** will be stored in the input string parameter, i.e. -** p_chip_id_str, when returns. -** -** Returns TRUE when found the target patch file, otherwise FALSE -** -*******************************************************************************/ -static uint8_t hw_config_findpatch(char *p_chip_id_str) -{ - DIR *dirp; - struct dirent *dp; - int filenamelen; - uint8_t retval = FALSE; - - BTHWDBG("Target name = [%s]", p_chip_id_str); - - if (strlen(fw_patchfile_name)> 0) - { - /* If specific filepath and filename have been given in run-time - * configuration /etc/bluetooth/bt_vendor.conf file, we will use them - * to concatenate the filename to open rather than searching a file - * matching to chipset name in the fw_patchfile_path folder. - */ - sprintf(p_chip_id_str, "%s", fw_patchfile_path); - if (fw_patchfile_path[strlen(fw_patchfile_path)- 1] != '/') - { - strcat(p_chip_id_str, "/"); - } - strcat(p_chip_id_str, fw_patchfile_name); - - ALOGI("FW patchfile: %s", p_chip_id_str); - return TRUE; - } - - if ((dirp = opendir(fw_patchfile_path)) != NULL) - { - /* Fetch next filename in patchfile directory */ - while ((dp = readdir(dirp)) != NULL) - { - /* Check if filename starts with chip-id name */ - if ((hw_strncmp(dp->d_name, p_chip_id_str, strlen(p_chip_id_str)) \ - ) == 0) - { - /* Check if it has .hcd extenstion */ - filenamelen = strlen(dp->d_name); - if ((filenamelen >= FW_PATCHFILE_EXTENSION_LEN) && - ((hw_strncmp( - &dp->d_name[filenamelen-FW_PATCHFILE_EXTENSION_LEN], \ - FW_PATCHFILE_EXTENSION, \ - FW_PATCHFILE_EXTENSION_LEN) \ - ) == 0)) - { - ALOGI("Found patchfile: %s/%s", \ - fw_patchfile_path, dp->d_name); - - /* Make sure length does not exceed maximum */ - if ((filenamelen + strlen(fw_patchfile_path)) > \ - FW_PATCHFILE_PATH_MAXLEN) - { - ALOGE("Invalid patchfile name (too long)"); - } - else - { - memset(p_chip_id_str, 0, FW_PATCHFILE_PATH_MAXLEN); - /* Found patchfile. Store location and name */ - strcpy(p_chip_id_str, fw_patchfile_path); - if (fw_patchfile_path[ \ - strlen(fw_patchfile_path)- 1 \ - ] != '/') - { - strcat(p_chip_id_str, "/"); - } - strcat(p_chip_id_str, dp->d_name); - retval = TRUE; - } - break; - } - } - } - - closedir(dirp); - - if (retval == FALSE) - { - /* Try again chip name without revision info */ - - int len = strlen(p_chip_id_str); - char *p = p_chip_id_str + len - 1; - - /* Scan backward and look for the first alphabet - which is not M or m - */ - while (len > 3) // BCM**** - { - if ((isdigit(*p)==0) && (*p != 'M') && (*p != 'm')) - break; - - p--; - len--; - } - - if (len > 3) - { - *p = 0; - retval = hw_config_findpatch(p_chip_id_str); - } - } - } - else - { - ALOGE("Could not open %s", fw_patchfile_path); - } - - return (retval); -} - -/******************************************************************************* -** -** Function hw_config_set_bdaddr -** -** Description Program controller's Bluetooth Device Address -** -** Returns TRUE, if valid address is sent -** FALSE, otherwise -** -*******************************************************************************/ -static uint8_t hw_config_set_bdaddr(HC_BT_HDR *p_buf) -{ - uint8_t retval = FALSE; - uint8_t *p = (uint8_t *) (p_buf + 1); - - ALOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X", - vnd_local_bd_addr[0], vnd_local_bd_addr[1], vnd_local_bd_addr[2], - vnd_local_bd_addr[3], vnd_local_bd_addr[4], vnd_local_bd_addr[5]); - - UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR); - *p++ = BD_ADDR_LEN; /* parameter length */ - *p++ = vnd_local_bd_addr[5]; - *p++ = vnd_local_bd_addr[4]; - *p++ = vnd_local_bd_addr[3]; - *p++ = vnd_local_bd_addr[2]; - *p++ = vnd_local_bd_addr[1]; - *p = vnd_local_bd_addr[0]; - - p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN; - hw_cfg_cb.state = HW_CFG_SET_BD_ADDR; - - retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_BD_ADDR, p_buf, \ - hw_config_cback); - - return (retval); -} - -/******************************************************************************* -** -** Function hw_config_cback -** -** Description Callback function for controller configuration -** -** Returns None -** -*******************************************************************************/ -void hw_config_cback(void *p_mem) -{ - HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; - char *p_name, *p_tmp; - uint8_t *p, status; - uint16_t opcode; - HC_BT_HDR *p_buf=NULL; - uint8_t is_proceeding = FALSE; - int i; - - 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); - - /* Ask a new buffer big enough to hold any HCI commands sent in here */ - if ((status == 0) && bt_vendor_cbacks) - p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ - HCI_CMD_MAX_LEN); - - if (p_buf != NULL) - { - p_buf->event = MSG_STACK_TO_HC_HCI_CMD; - p_buf->offset = 0; - p_buf->len = 0; - p_buf->layer_specific = 0; - - p = (uint8_t *) (p_buf + 1); - - switch (hw_cfg_cb.state) - { - case HW_CFG_SET_UART_BAUD_1: - /* update baud rate of host's UART port */ - ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); - userial_vendor_set_baud( \ - line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ - ); - - /* read local name */ - UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME); - *p = 0; /* parameter length */ - - p_buf->len = HCI_CMD_PREAMBLE_SIZE; - hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME; - - is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \ - p_buf, hw_config_cback); - break; - - case HW_CFG_READ_LOCAL_NAME: - p_tmp = p_name = (char *) (p_evt_buf + 1) + \ - HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING; - - for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++) - *(p_name+i) = toupper(*(p_name+i)); - - if ((p_name = strstr(p_name, "BCM")) != NULL) - { - strncpy(hw_cfg_cb.local_chip_name, p_name, \ - LOCAL_NAME_BUFFER_LEN-1); - } - else - { - strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \ - LOCAL_NAME_BUFFER_LEN-1); - p_name = p_tmp; - } - - hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0; - - BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name); - - if ((status = hw_config_findpatch(p_name)) == TRUE) - { - if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1) - { - ALOGE("vendor lib preload failed to open [%s]", p_name); - } - else - { - /* vsc_download_minidriver */ - UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV); - *p = 0; /* parameter length */ - - p_buf->len = HCI_CMD_PREAMBLE_SIZE; - hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER; - - is_proceeding = bt_vendor_cbacks->xmit_cb( \ - HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \ - hw_config_cback); - } - } - else - { - ALOGE( \ - "vendor lib preload failed to locate firmware patch file" \ - ); - } - - if (is_proceeding == FALSE) - { - is_proceeding = hw_config_set_bdaddr(p_buf); - } - break; - - case HW_CFG_DL_MINIDRIVER: - /* give time for placing firmware in download mode */ - ms_delay(50); - hw_cfg_cb.state = HW_CFG_DL_FW_PATCH; - /* fall through intentionally */ - case HW_CFG_DL_FW_PATCH: - p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE); - if (p_buf->len > 0) - { - if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \ - (opcode == HCI_VSC_LAUNCH_RAM)) - { - ALOGW("firmware patch file might be altered!"); - } - else - { - p_buf->len += read(hw_cfg_cb.fw_fd, \ - p+HCI_CMD_PREAMBLE_SIZE,\ - *(p+HCD_REC_PAYLOAD_LEN_BYTE)); - STREAM_TO_UINT16(opcode,p); - is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \ - p_buf, hw_config_cback); - break; - } - } - - close(hw_cfg_cb.fw_fd); - hw_cfg_cb.fw_fd = -1; - - /* Normally the firmware patch configuration file - * sets the new starting baud rate at 115200. - * So, we need update host's baud rate accordingly. - */ - ALOGI("bt vendor lib: set UART baud 115200"); - userial_vendor_set_baud(USERIAL_BAUD_115200); - - /* Next, we would like to boost baud rate up again - * to desired working speed. - */ - hw_cfg_cb.f_set_baud_2 = TRUE; - - /* Check if we need to pause a few hundred milliseconds - * before sending down any HCI command. - */ - ms_delay(look_up_fw_settlement_delay()); - - /* fall through intentionally */ - case HW_CFG_START: - if (UART_TARGET_BAUD_RATE > 3000000) - { - /* set UART clock to 48MHz */ - UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING); - *p++ = 1; /* parameter length */ - *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */ - - p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1; - hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK; - - is_proceeding = bt_vendor_cbacks->xmit_cb( \ - HCI_VSC_WRITE_UART_CLOCK_SETTING, \ - p_buf, hw_config_cback); - break; - } - /* fall through intentionally */ - case HW_CFG_SET_UART_CLOCK: - /* set controller's UART baud rate to 3M */ - UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE); - *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */ - *p++ = 0; /* encoded baud rate */ - *p++ = 0; /* use encoded form */ - UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE); - - p_buf->len = HCI_CMD_PREAMBLE_SIZE + \ - UPDATE_BAUDRATE_CMD_PARAM_SIZE; - hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \ - HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1; - - is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \ - p_buf, hw_config_cback); - break; - - case HW_CFG_SET_UART_BAUD_2: - /* update baud rate of host's UART port */ - ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); - userial_vendor_set_baud( \ - line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ - ); - - if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) - break; - - /* fall through intentionally */ - case HW_CFG_SET_BD_ADDR: - ALOGI("vendor lib fwcfg completed"); - bt_vendor_cbacks->dealloc(p_buf); - bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); - - hw_cfg_cb.state = 0; - - if (hw_cfg_cb.fw_fd != -1) - { - close(hw_cfg_cb.fw_fd); - hw_cfg_cb.fw_fd = -1; - } - - is_proceeding = TRUE; - break; - } // switch(hw_cfg_cb.state) - } // if (p_buf != NULL) - - /* Free the RX event buffer */ - if (bt_vendor_cbacks) - bt_vendor_cbacks->dealloc(p_evt_buf); - - if (is_proceeding == FALSE) - { - ALOGE("vendor lib fwcfg aborted!!!"); - if (bt_vendor_cbacks) - { - if (p_buf != NULL) - bt_vendor_cbacks->dealloc(p_buf); - - bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); - } - - if (hw_cfg_cb.fw_fd != -1) - { - close(hw_cfg_cb.fw_fd); - hw_cfg_cb.fw_fd = -1; - } - - hw_cfg_cb.state = 0; - } -} - -/****************************************************************************** -** LPM Static Functions -******************************************************************************/ - -/******************************************************************************* -** -** Function hw_lpm_ctrl_cback -** -** Description Callback function for lpm enable/disable rquest -** -** Returns None -** -*******************************************************************************/ -void hw_lpm_ctrl_cback(void *p_mem) -{ - 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; - } - - if (bt_vendor_cbacks) - { - bt_vendor_cbacks->lpm_cb(status); - bt_vendor_cbacks->dealloc(p_evt_buf); - } -} - - -#if (SCO_CFG_INCLUDED == TRUE) -/***************************************************************************** -** SCO Configuration Static Functions -*****************************************************************************/ - -/******************************************************************************* -** -** Function hw_sco_cfg_cback -** -** Description Callback function for SCO configuration rquest -** -** Returns None -** -*******************************************************************************/ -void hw_sco_cfg_cback(void *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; - - p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; - STREAM_TO_UINT16(opcode,p); - - /* 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) - { - 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) - { - 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); - - if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,\ - p_buf, hw_sco_cfg_cback)) == FALSE) - { - bt_vendor_cbacks->dealloc(p_buf); - } - else - return; - } - } -#endif // !SCO_USE_I2S_INTERFACE - -if (bt_vendor_cbacks) - bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); -} -#endif // SCO_CFG_INCLUDED - -/***************************************************************************** -** Hardware Configuration Interface Functions -*****************************************************************************/ - - -/******************************************************************************* -** -** Function hw_config_start -** -** Description Kick off controller initialization process -** -** Returns None -** -*******************************************************************************/ -void hw_config_start(void) -{ - HC_BT_HDR *p_buf = NULL; - uint8_t *p; - - hw_cfg_cb.state = 0; - hw_cfg_cb.fw_fd = -1; - hw_cfg_cb.f_set_baud_2 = FALSE; - - /* Start from sending HCI_RESET */ - - if (bt_vendor_cbacks) - { - 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 */ - - hw_cfg_cb.state = HW_CFG_START; - - bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback); - } - else - { - if (bt_vendor_cbacks) - { - ALOGE("vendor lib fw conf aborted [no buffer]"); - bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); - } - } -} - -/******************************************************************************* -** -** Function hw_lpm_enable -** -** Description Enalbe/Disable LPM -** -** Returns TRUE/FALSE -** -*******************************************************************************/ -uint8_t hw_lpm_enable(uint8_t turn_on) -{ - HC_BT_HDR *p_buf = NULL; - uint8_t *p; - uint8_t ret = FALSE; - - if (bt_vendor_cbacks) - p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ - HCI_CMD_PREAMBLE_SIZE + \ - LPM_CMD_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 + LPM_CMD_PARAM_SIZE; - - p = (uint8_t *) (p_buf + 1); - UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE); - *p++ = LPM_CMD_PARAM_SIZE; /* parameter length */ - - if (turn_on) - { - memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE); - } - else - { - memset(p, 0, LPM_CMD_PARAM_SIZE); - } - - if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \ - hw_lpm_ctrl_cback)) == FALSE) - { - bt_vendor_cbacks->dealloc(p_buf); - } - } - - if ((ret == FALSE) && bt_vendor_cbacks) - bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL); - - return ret; -} - -/******************************************************************************* -** -** Function hw_lpm_get_idle_timeout -** -** Description Calculate idle time based on host stack idle threshold -** -** Returns idle timeout value -** -*******************************************************************************/ -uint32_t hw_lpm_get_idle_timeout(void) -{ - uint32_t timeout_ms; - - /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of - * host stack idle threshold (in 300ms/25ms) - */ - timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold \ - * LPM_IDLE_TIMEOUT_MULTIPLE; - - if (strstr(hw_cfg_cb.local_chip_name, "BCM4325") != NULL) - timeout_ms *= 25; // 12.5 or 25 ? - else - timeout_ms *= 300; - - return timeout_ms; -} - -/******************************************************************************* -** -** Function hw_lpm_set_wake_state -** -** Description Assert/Deassert BT_WAKE -** -** Returns None -** -*******************************************************************************/ -void hw_lpm_set_wake_state(uint8_t wake_assert) -{ - uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT; - - upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity); -} - -#if (SCO_CFG_INCLUDED == TRUE) -/******************************************************************************* -** -** Function hw_sco_config -** -** Description Configure SCO related hardware settings -** -** Returns None -** -*******************************************************************************/ -void hw_sco_config(void) -{ - HC_BT_HDR *p_buf = NULL; - uint8_t *p, ret; - -#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 - - 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); -#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]); - -#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 ((ret=bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_cfg_cback)) \ - == FALSE) - { - bt_vendor_cbacks->dealloc(p_buf); - } - else - return; - } - - if (bt_vendor_cbacks) - { - ALOGE("vendor lib scocfg aborted"); - bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_FAIL); - } -} -#endif // SCO_CFG_INCLUDED - -/******************************************************************************* -** -** Function hw_set_patch_file_path -** -** Description Set the location of firmware patch file -** -** Returns 0 : Success -** Otherwise : Fail -** -*******************************************************************************/ -int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param) -{ - - strcpy(fw_patchfile_path, p_conf_value); - - return 0; -} - -/******************************************************************************* -** -** Function hw_set_patch_file_name -** -** Description Give the specific firmware patch filename -** -** Returns 0 : Success -** Otherwise : Fail -** -*******************************************************************************/ -int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param) -{ - - strcpy(fw_patchfile_name, p_conf_value); - - return 0; -} - -#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) -/******************************************************************************* -** -** Function hw_set_patch_settlement_delay -** -** Description Give the specific firmware patch settlement time in milliseconds -** -** Returns 0 : Success -** Otherwise : Fail -** -*******************************************************************************/ -int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param) -{ - fw_patch_settlement_delay = atoi(p_conf_value); - - return 0; -} -#endif //VENDOR_LIB_RUNTIME_TUNING_ENABLED - |