summaryrefslogtreecommitdiffstats
path: root/libbt/src/hardware.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbt/src/hardware.c')
-rw-r--r--libbt/src/hardware.c1155
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
-