Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2009-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  Filename:      hardware.c
     22  *
     23  *  Description:   Contains controller-specific functions, like
     24  *                      firmware patch download
     25  *                      low power mode operations
     26  *
     27  ******************************************************************************/
     28 
     29 #define LOG_TAG "bt_hwcfg"
     30 
     31 #include <utils/Log.h>
     32 #include <sys/types.h>
     33 #include <sys/stat.h>
     34 #include <signal.h>
     35 #include <time.h>
     36 #include <errno.h>
     37 #include <fcntl.h>
     38 #include <dirent.h>
     39 #include <ctype.h>
     40 #include <cutils/properties.h>
     41 #include <stdlib.h>
     42 #include "bt_hci_bdroid.h"
     43 #include "bt_vendor_brcm.h"
     44 #include "userial.h"
     45 #include "userial_vendor.h"
     46 #include "upio.h"
     47 
     48 /******************************************************************************
     49 **  Constants & Macros
     50 ******************************************************************************/
     51 
     52 #ifndef BTHW_DBG
     53 #define BTHW_DBG FALSE
     54 #endif
     55 
     56 #if (BTHW_DBG == TRUE)
     57 #define BTHWDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
     58 #else
     59 #define BTHWDBG(param, ...) {}
     60 #endif
     61 
     62 #define FW_PATCHFILE_EXTENSION      ".hcd"
     63 #define FW_PATCHFILE_EXTENSION_LEN  4
     64 #define FW_PATCHFILE_PATH_MAXLEN    248 /* Local_Name length of return of
     65                                            HCI_Read_Local_Name */
     66 
     67 #define HCI_CMD_MAX_LEN             258
     68 
     69 #define HCI_RESET                               0x0C03
     70 #define HCI_VSC_WRITE_UART_CLOCK_SETTING        0xFC45
     71 #define HCI_VSC_UPDATE_BAUDRATE                 0xFC18
     72 #define HCI_READ_LOCAL_NAME                     0x0C14
     73 #define HCI_VSC_DOWNLOAD_MINIDRV                0xFC2E
     74 #define HCI_VSC_WRITE_BD_ADDR                   0xFC01
     75 #define HCI_VSC_WRITE_SLEEP_MODE                0xFC27
     76 #define HCI_VSC_WRITE_SCO_PCM_INT_PARAM         0xFC1C
     77 #define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM     0xFC1E
     78 #define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM    0xFC6D
     79 #define HCI_VSC_LAUNCH_RAM                      0xFC4E
     80 #define HCI_READ_LOCAL_BDADDR                   0x1009
     81 
     82 #define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE        5
     83 #define HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING      6
     84 #define HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY     6
     85 #define HCI_EVT_CMD_CMPL_OPCODE                 3
     86 #define LPM_CMD_PARAM_SIZE                      12
     87 #define UPDATE_BAUDRATE_CMD_PARAM_SIZE          6
     88 #define HCI_CMD_PREAMBLE_SIZE                   3
     89 #define HCD_REC_PAYLOAD_LEN_BYTE                2
     90 #define BD_ADDR_LEN                             6
     91 #define LOCAL_NAME_BUFFER_LEN                   32
     92 #define LOCAL_BDADDR_PATH_BUFFER_LEN            256
     93 
     94 #define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
     95 #define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
     96 #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);}
     97 
     98 /******************************************************************************
     99 **  Local type definitions
    100 ******************************************************************************/
    101 
    102 /* Hardware Configuration State */
    103 enum {
    104     HW_CFG_START = 1,
    105     HW_CFG_SET_UART_CLOCK,
    106     HW_CFG_SET_UART_BAUD_1,
    107     HW_CFG_READ_LOCAL_NAME,
    108     HW_CFG_DL_MINIDRIVER,
    109     HW_CFG_DL_FW_PATCH,
    110     HW_CFG_SET_UART_BAUD_2,
    111     HW_CFG_SET_BD_ADDR
    112 #if (USE_CONTROLLER_BDADDR == TRUE)
    113     , HW_CFG_READ_BD_ADDR
    114 #endif
    115 };
    116 
    117 /* h/w config control block */
    118 typedef struct
    119 {
    120     uint8_t state;                          /* Hardware configuration state */
    121     int     fw_fd;                          /* FW patch file fd */
    122     uint8_t f_set_baud_2;                   /* Baud rate switch state */
    123     char    local_chip_name[LOCAL_NAME_BUFFER_LEN];
    124 } bt_hw_cfg_cb_t;
    125 
    126 /* low power mode parameters */
    127 typedef struct
    128 {
    129     uint8_t sleep_mode;                     /* 0(disable),1(UART),9(H5) */
    130     uint8_t host_stack_idle_threshold;      /* Unit scale 300ms/25ms */
    131     uint8_t host_controller_idle_threshold; /* Unit scale 300ms/25ms */
    132     uint8_t bt_wake_polarity;               /* 0=Active Low, 1= Active High */
    133     uint8_t host_wake_polarity;             /* 0=Active Low, 1= Active High */
    134     uint8_t allow_host_sleep_during_sco;
    135     uint8_t combine_sleep_mode_and_lpm;
    136     uint8_t enable_uart_txd_tri_state;      /* UART_TXD Tri-State */
    137     uint8_t sleep_guard_time;               /* sleep guard time in 12.5ms */
    138     uint8_t wakeup_guard_time;              /* wakeup guard time in 12.5ms */
    139     uint8_t txd_config;                     /* TXD is high in sleep state */
    140     uint8_t pulsed_host_wake;               /* pulsed host wake if mode = 1 */
    141 } bt_lpm_param_t;
    142 
    143 /* Firmware re-launch settlement time */
    144 typedef struct {
    145     const char *chipset_name;
    146     const uint32_t delay_time;
    147 } fw_settlement_entry_t;
    148 
    149 
    150 /******************************************************************************
    151 **  Externs
    152 ******************************************************************************/
    153 
    154 void hw_config_cback(void *p_evt_buf);
    155 extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN];
    156 
    157 
    158 /******************************************************************************
    159 **  Static variables
    160 ******************************************************************************/
    161 
    162 static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION;
    163 static char fw_patchfile_name[128] = { 0 };
    164 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
    165 static int fw_patch_settlement_delay = -1;
    166 #endif
    167 
    168 static bt_hw_cfg_cb_t hw_cfg_cb;
    169 
    170 static bt_lpm_param_t lpm_param =
    171 {
    172     LPM_SLEEP_MODE,
    173     LPM_IDLE_THRESHOLD,
    174     LPM_HC_IDLE_THRESHOLD,
    175     LPM_BT_WAKE_POLARITY,
    176     LPM_HOST_WAKE_POLARITY,
    177     LPM_ALLOW_HOST_SLEEP_DURING_SCO,
    178     LPM_COMBINE_SLEEP_MODE_AND_LPM,
    179     LPM_ENABLE_UART_TXD_TRI_STATE,
    180     0,  /* not applicable */
    181     0,  /* not applicable */
    182     0,  /* not applicable */
    183     LPM_PULSED_HOST_WAKE
    184 };
    185 
    186 #if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
    187 static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] =
    188 {
    189     SCO_PCM_ROUTING,
    190     SCO_PCM_IF_CLOCK_RATE,
    191     SCO_PCM_IF_FRAME_TYPE,
    192     SCO_PCM_IF_SYNC_MODE,
    193     SCO_PCM_IF_CLOCK_MODE
    194 };
    195 
    196 static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] =
    197 {
    198     PCM_DATA_FMT_SHIFT_MODE,
    199     PCM_DATA_FMT_FILL_BITS,
    200     PCM_DATA_FMT_FILL_METHOD,
    201     PCM_DATA_FMT_FILL_NUM,
    202     PCM_DATA_FMT_JUSTIFY_MODE
    203 };
    204 #else
    205 static uint8_t bt_sco_param[SCO_I2SPCM_PARAM_SIZE] =
    206 {
    207     SCO_I2SPCM_IF_MODE,
    208     SCO_I2SPCM_IF_ROLE,
    209     SCO_I2SPCM_IF_SAMPLE_RATE,
    210     SCO_I2SPCM_IF_CLOCK_RATE
    211 };
    212 #endif
    213 
    214 /*
    215  * The look-up table of recommended firmware settlement delay (milliseconds) on
    216  * known chipsets.
    217  */
    218 static const fw_settlement_entry_t fw_settlement_table[] = {
    219     {"BCM43241", 200},
    220     {(const char *) NULL, 100}  // Giving the generic fw settlement delay setting.
    221 };
    222 
    223 /******************************************************************************
    224 **  Static functions
    225 ******************************************************************************/
    226 
    227 /******************************************************************************
    228 **  Controller Initialization Static Functions
    229 ******************************************************************************/
    230 
    231 /*******************************************************************************
    232 **
    233 ** Function        look_up_fw_settlement_delay
    234 **
    235 ** Description     If FW_PATCH_SETTLEMENT_DELAY_MS has not been explicitly
    236 **                 re-defined in the platform specific build-time configuration
    237 **                 file, we will search into the look-up table for a
    238 **                 recommended firmware settlement delay value.
    239 **
    240 **                 Although the settlement time might be also related to board
    241 **                 configurations such as the crystal clocking speed.
    242 **
    243 ** Returns         Firmware settlement delay
    244 **
    245 *******************************************************************************/
    246 uint32_t look_up_fw_settlement_delay (void)
    247 {
    248     uint32_t ret_value;
    249     fw_settlement_entry_t *p_entry;
    250 
    251     if (FW_PATCH_SETTLEMENT_DELAY_MS > 0)
    252     {
    253         ret_value = FW_PATCH_SETTLEMENT_DELAY_MS;
    254     }
    255 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
    256     else if (fw_patch_settlement_delay >= 0)
    257     {
    258         ret_value = fw_patch_settlement_delay;
    259     }
    260 #endif
    261     else
    262     {
    263         p_entry = (fw_settlement_entry_t *)fw_settlement_table;
    264 
    265         while (p_entry->chipset_name != NULL)
    266         {
    267             if (strstr(hw_cfg_cb.local_chip_name, p_entry->chipset_name)!=NULL)
    268             {
    269                 break;
    270             }
    271 
    272             p_entry++;
    273         }
    274 
    275         ret_value = p_entry->delay_time;
    276     }
    277 
    278     BTHWDBG( "Settlement delay -- %d ms", ret_value);
    279 
    280     return (ret_value);
    281 }
    282 
    283 /*******************************************************************************
    284 **
    285 ** Function        ms_delay
    286 **
    287 ** Description     sleep unconditionally for timeout milliseconds
    288 **
    289 ** Returns         None
    290 **
    291 *******************************************************************************/
    292 void ms_delay (uint32_t timeout)
    293 {
    294     struct timespec delay;
    295     int err;
    296 
    297     if (timeout == 0)
    298         return;
    299 
    300     delay.tv_sec = timeout / 1000;
    301     delay.tv_nsec = 1000 * 1000 * (timeout%1000);
    302 
    303     /* [u]sleep can't be used because it uses SIGALRM */
    304     do {
    305         err = nanosleep(&delay, &delay);
    306     } while (err < 0 && errno ==EINTR);
    307 }
    308 
    309 /*******************************************************************************
    310 **
    311 ** Function        line_speed_to_userial_baud
    312 **
    313 ** Description     helper function converts line speed number into USERIAL baud
    314 **                 rate symbol
    315 **
    316 ** Returns         unit8_t (USERIAL baud symbol)
    317 **
    318 *******************************************************************************/
    319 uint8_t line_speed_to_userial_baud(uint32_t line_speed)
    320 {
    321     uint8_t baud;
    322 
    323     if (line_speed == 4000000)
    324         baud = USERIAL_BAUD_4M;
    325     else if (line_speed == 3000000)
    326         baud = USERIAL_BAUD_3M;
    327     else if (line_speed == 2000000)
    328         baud = USERIAL_BAUD_2M;
    329     else if (line_speed == 1000000)
    330         baud = USERIAL_BAUD_1M;
    331     else if (line_speed == 921600)
    332         baud = USERIAL_BAUD_921600;
    333     else if (line_speed == 460800)
    334         baud = USERIAL_BAUD_460800;
    335     else if (line_speed == 230400)
    336         baud = USERIAL_BAUD_230400;
    337     else if (line_speed == 115200)
    338         baud = USERIAL_BAUD_115200;
    339     else if (line_speed == 57600)
    340         baud = USERIAL_BAUD_57600;
    341     else if (line_speed == 19200)
    342         baud = USERIAL_BAUD_19200;
    343     else if (line_speed == 9600)
    344         baud = USERIAL_BAUD_9600;
    345     else if (line_speed == 1200)
    346         baud = USERIAL_BAUD_1200;
    347     else if (line_speed == 600)
    348         baud = USERIAL_BAUD_600;
    349     else
    350     {
    351         ALOGE( "userial vendor: unsupported baud speed %d", line_speed);
    352         baud = USERIAL_BAUD_115200;
    353     }
    354 
    355     return baud;
    356 }
    357 
    358 
    359 /*******************************************************************************
    360 **
    361 ** Function         hw_strncmp
    362 **
    363 ** Description      Used to compare two strings in caseless
    364 **
    365 ** Returns          0: match, otherwise: not match
    366 **
    367 *******************************************************************************/
    368 static int hw_strncmp (const char *p_str1, const char *p_str2, const int len)
    369 {
    370     int i;
    371 
    372     if (!p_str1 || !p_str2)
    373         return (1);
    374 
    375     for (i = 0; i < len; i++)
    376     {
    377         if (toupper(p_str1[i]) != toupper(p_str2[i]))
    378             return (i+1);
    379     }
    380 
    381     return 0;
    382 }
    383 
    384 /*******************************************************************************
    385 **
    386 ** Function         hw_config_findpatch
    387 **
    388 ** Description      Search for a proper firmware patch file
    389 **                  The selected firmware patch file name with full path
    390 **                  will be stored in the input string parameter, i.e.
    391 **                  p_chip_id_str, when returns.
    392 **
    393 ** Returns          TRUE when found the target patch file, otherwise FALSE
    394 **
    395 *******************************************************************************/
    396 static uint8_t hw_config_findpatch(char *p_chip_id_str)
    397 {
    398     DIR *dirp;
    399     struct dirent *dp;
    400     int filenamelen;
    401     uint8_t retval = FALSE;
    402 
    403     BTHWDBG("Target name = [%s]", p_chip_id_str);
    404 
    405     if (strlen(fw_patchfile_name)> 0)
    406     {
    407         /* If specific filepath and filename have been given in run-time
    408          * configuration /etc/bluetooth/bt_vendor.conf file, we will use them
    409          * to concatenate the filename to open rather than searching a file
    410          * matching to chipset name in the fw_patchfile_path folder.
    411          */
    412         sprintf(p_chip_id_str, "%s", fw_patchfile_path);
    413         if (fw_patchfile_path[strlen(fw_patchfile_path)- 1] != '/')
    414         {
    415             strcat(p_chip_id_str, "/");
    416         }
    417         strcat(p_chip_id_str, fw_patchfile_name);
    418 
    419         ALOGI("FW patchfile: %s", p_chip_id_str);
    420         return TRUE;
    421     }
    422 
    423     if ((dirp = opendir(fw_patchfile_path)) != NULL)
    424     {
    425         /* Fetch next filename in patchfile directory */
    426         while ((dp = readdir(dirp)) != NULL)
    427         {
    428             /* Check if filename starts with chip-id name */
    429             if ((hw_strncmp(dp->d_name, p_chip_id_str, strlen(p_chip_id_str)) \
    430                 ) == 0)
    431             {
    432                 /* Check if it has .hcd extenstion */
    433                 filenamelen = strlen(dp->d_name);
    434                 if ((filenamelen >= FW_PATCHFILE_EXTENSION_LEN) &&
    435                     ((hw_strncmp(
    436                           &dp->d_name[filenamelen-FW_PATCHFILE_EXTENSION_LEN], \
    437                           FW_PATCHFILE_EXTENSION, \
    438                           FW_PATCHFILE_EXTENSION_LEN) \
    439                      ) == 0))
    440                 {
    441                     ALOGI("Found patchfile: %s/%s", \
    442                         fw_patchfile_path, dp->d_name);
    443 
    444                     /* Make sure length does not exceed maximum */
    445                     if ((filenamelen + strlen(fw_patchfile_path)) > \
    446                          FW_PATCHFILE_PATH_MAXLEN)
    447                     {
    448                         ALOGE("Invalid patchfile name (too long)");
    449                     }
    450                     else
    451                     {
    452                         memset(p_chip_id_str, 0, FW_PATCHFILE_PATH_MAXLEN);
    453                         /* Found patchfile. Store location and name */
    454                         strcpy(p_chip_id_str, fw_patchfile_path);
    455                         if (fw_patchfile_path[ \
    456                             strlen(fw_patchfile_path)- 1 \
    457                             ] != '/')
    458                         {
    459                             strcat(p_chip_id_str, "/");
    460                         }
    461                         strcat(p_chip_id_str, dp->d_name);
    462                         retval = TRUE;
    463                     }
    464                     break;
    465                 }
    466             }
    467         }
    468 
    469         closedir(dirp);
    470 
    471         if (retval == FALSE)
    472         {
    473             /* Try again chip name without revision info */
    474 
    475             int len = strlen(p_chip_id_str);
    476             char *p = p_chip_id_str + len - 1;
    477 
    478             /* Scan backward and look for the first alphabet
    479                which is not M or m
    480             */
    481             while (len > 3) // BCM****
    482             {
    483                 if ((isdigit(*p)==0) && (*p != 'M') && (*p != 'm'))
    484                     break;
    485 
    486                 p--;
    487                 len--;
    488             }
    489 
    490             if (len > 3)
    491             {
    492                 *p = 0;
    493                 retval = hw_config_findpatch(p_chip_id_str);
    494             }
    495         }
    496     }
    497     else
    498     {
    499         ALOGE("Could not open %s", fw_patchfile_path);
    500     }
    501 
    502     return (retval);
    503 }
    504 
    505 /*******************************************************************************
    506 **
    507 ** Function         hw_config_set_bdaddr
    508 **
    509 ** Description      Program controller's Bluetooth Device Address
    510 **
    511 ** Returns          TRUE, if valid address is sent
    512 **                  FALSE, otherwise
    513 **
    514 *******************************************************************************/
    515 static uint8_t hw_config_set_bdaddr(HC_BT_HDR *p_buf)
    516 {
    517     uint8_t retval = FALSE;
    518     uint8_t *p = (uint8_t *) (p_buf + 1);
    519 
    520     ALOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X",
    521         vnd_local_bd_addr[0], vnd_local_bd_addr[1], vnd_local_bd_addr[2],
    522         vnd_local_bd_addr[3], vnd_local_bd_addr[4], vnd_local_bd_addr[5]);
    523 
    524     UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR);
    525     *p++ = BD_ADDR_LEN; /* parameter length */
    526     *p++ = vnd_local_bd_addr[5];
    527     *p++ = vnd_local_bd_addr[4];
    528     *p++ = vnd_local_bd_addr[3];
    529     *p++ = vnd_local_bd_addr[2];
    530     *p++ = vnd_local_bd_addr[1];
    531     *p = vnd_local_bd_addr[0];
    532 
    533     p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN;
    534     hw_cfg_cb.state = HW_CFG_SET_BD_ADDR;
    535 
    536     retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_BD_ADDR, p_buf, \
    537                                  hw_config_cback);
    538 
    539     return (retval);
    540 }
    541 
    542 #if (USE_CONTROLLER_BDADDR == TRUE)
    543 /*******************************************************************************
    544 **
    545 ** Function         hw_config_read_bdaddr
    546 **
    547 ** Description      Read controller's Bluetooth Device Address
    548 **
    549 ** Returns          TRUE, if valid address is sent
    550 **                  FALSE, otherwise
    551 **
    552 *******************************************************************************/
    553 static uint8_t hw_config_read_bdaddr(HC_BT_HDR *p_buf)
    554 {
    555     uint8_t retval = FALSE;
    556     uint8_t *p = (uint8_t *) (p_buf + 1);
    557 
    558     UINT16_TO_STREAM(p, HCI_READ_LOCAL_BDADDR);
    559     *p = 0; /* parameter length */
    560 
    561     p_buf->len = HCI_CMD_PREAMBLE_SIZE;
    562     hw_cfg_cb.state = HW_CFG_READ_BD_ADDR;
    563 
    564     retval = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_BDADDR, p_buf, \
    565                                  hw_config_cback);
    566 
    567     return (retval);
    568 }
    569 #endif // (USE_CONTROLLER_BDADDR == TRUE)
    570 
    571 /*******************************************************************************
    572 **
    573 ** Function         hw_config_cback
    574 **
    575 ** Description      Callback function for controller configuration
    576 **
    577 ** Returns          None
    578 **
    579 *******************************************************************************/
    580 void hw_config_cback(void *p_mem)
    581 {
    582     HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
    583     char        *p_name, *p_tmp;
    584     uint8_t     *p, status;
    585     uint16_t    opcode;
    586     HC_BT_HDR  *p_buf=NULL;
    587     uint8_t     is_proceeding = FALSE;
    588     int         i;
    589 #if (USE_CONTROLLER_BDADDR == TRUE)
    590     const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
    591 #endif
    592 
    593     status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
    594     p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
    595     STREAM_TO_UINT16(opcode,p);
    596 
    597     /* Ask a new buffer big enough to hold any HCI commands sent in here */
    598     if ((status == 0) && bt_vendor_cbacks)
    599         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
    600                                                        HCI_CMD_MAX_LEN);
    601 
    602     if (p_buf != NULL)
    603     {
    604         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
    605         p_buf->offset = 0;
    606         p_buf->len = 0;
    607         p_buf->layer_specific = 0;
    608 
    609         p = (uint8_t *) (p_buf + 1);
    610 
    611         switch (hw_cfg_cb.state)
    612         {
    613             case HW_CFG_SET_UART_BAUD_1:
    614                 /* update baud rate of host's UART port */
    615                 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
    616                 userial_vendor_set_baud( \
    617                     line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
    618                 );
    619 
    620                 /* read local name */
    621                 UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME);
    622                 *p = 0; /* parameter length */
    623 
    624                 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
    625                 hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME;
    626 
    627                 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \
    628                                                     p_buf, hw_config_cback);
    629                 break;
    630 
    631             case HW_CFG_READ_LOCAL_NAME:
    632                 p_tmp = p_name = (char *) (p_evt_buf + 1) + \
    633                          HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING;
    634 
    635                 for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++)
    636                     *(p_name+i) = toupper(*(p_name+i));
    637 
    638                 if ((p_name = strstr(p_name, "BCM")) != NULL)
    639                 {
    640                     strncpy(hw_cfg_cb.local_chip_name, p_name, \
    641                             LOCAL_NAME_BUFFER_LEN-1);
    642                 }
    643                 else
    644                 {
    645                     strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \
    646                             LOCAL_NAME_BUFFER_LEN-1);
    647                     p_name = p_tmp;
    648                 }
    649 
    650                 hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0;
    651 
    652                 BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name);
    653 
    654                 if ((status = hw_config_findpatch(p_name)) == TRUE)
    655                 {
    656                     if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1)
    657                     {
    658                         ALOGE("vendor lib preload failed to open [%s]", p_name);
    659                     }
    660                     else
    661                     {
    662                         /* vsc_download_minidriver */
    663                         UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV);
    664                         *p = 0; /* parameter length */
    665 
    666                         p_buf->len = HCI_CMD_PREAMBLE_SIZE;
    667                         hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER;
    668 
    669                         is_proceeding = bt_vendor_cbacks->xmit_cb( \
    670                                             HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \
    671                                             hw_config_cback);
    672                     }
    673                 }
    674                 else
    675                 {
    676                     ALOGE( \
    677                     "vendor lib preload failed to locate firmware patch file" \
    678                     );
    679                 }
    680 
    681                 if (is_proceeding == FALSE)
    682                 {
    683                     is_proceeding = hw_config_set_bdaddr(p_buf);
    684                 }
    685                 break;
    686 
    687             case HW_CFG_DL_MINIDRIVER:
    688                 /* give time for placing firmware in download mode */
    689                 ms_delay(50);
    690                 hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
    691                 /* fall through intentionally */
    692             case HW_CFG_DL_FW_PATCH:
    693                 p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE);
    694                 if (p_buf->len > 0)
    695                 {
    696                     if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \
    697                         (opcode == HCI_VSC_LAUNCH_RAM))
    698                     {
    699                         ALOGW("firmware patch file might be altered!");
    700                     }
    701                     else
    702                     {
    703                         p_buf->len += read(hw_cfg_cb.fw_fd, \
    704                                            p+HCI_CMD_PREAMBLE_SIZE,\
    705                                            *(p+HCD_REC_PAYLOAD_LEN_BYTE));
    706                         STREAM_TO_UINT16(opcode,p);
    707                         is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \
    708                                                 p_buf, hw_config_cback);
    709                         break;
    710                     }
    711                 }
    712 
    713                 close(hw_cfg_cb.fw_fd);
    714                 hw_cfg_cb.fw_fd = -1;
    715 
    716                 /* Normally the firmware patch configuration file
    717                  * sets the new starting baud rate at 115200.
    718                  * So, we need update host's baud rate accordingly.
    719                  */
    720                 ALOGI("bt vendor lib: set UART baud 115200");
    721                 userial_vendor_set_baud(USERIAL_BAUD_115200);
    722 
    723                 /* Next, we would like to boost baud rate up again
    724                  * to desired working speed.
    725                  */
    726                 hw_cfg_cb.f_set_baud_2 = TRUE;
    727 
    728                 /* Check if we need to pause a few hundred milliseconds
    729                  * before sending down any HCI command.
    730                  */
    731                 ms_delay(look_up_fw_settlement_delay());
    732 
    733                 /* fall through intentionally */
    734             case HW_CFG_START:
    735                 if (UART_TARGET_BAUD_RATE > 3000000)
    736                 {
    737                     /* set UART clock to 48MHz */
    738                     UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING);
    739                     *p++ = 1; /* parameter length */
    740                     *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */
    741 
    742                     p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1;
    743                     hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK;
    744 
    745                     is_proceeding = bt_vendor_cbacks->xmit_cb( \
    746                                         HCI_VSC_WRITE_UART_CLOCK_SETTING, \
    747                                         p_buf, hw_config_cback);
    748                     break;
    749                 }
    750                 /* fall through intentionally */
    751             case HW_CFG_SET_UART_CLOCK:
    752                 /* set controller's UART baud rate to 3M */
    753                 UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
    754                 *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */
    755                 *p++ = 0; /* encoded baud rate */
    756                 *p++ = 0; /* use encoded form */
    757                 UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);
    758 
    759                 p_buf->len = HCI_CMD_PREAMBLE_SIZE + \
    760                              UPDATE_BAUDRATE_CMD_PARAM_SIZE;
    761                 hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \
    762                             HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1;
    763 
    764                 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \
    765                                                     p_buf, hw_config_cback);
    766                 break;
    767 
    768             case HW_CFG_SET_UART_BAUD_2:
    769                 /* update baud rate of host's UART port */
    770                 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
    771                 userial_vendor_set_baud( \
    772                     line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
    773                 );
    774 
    775 #if (USE_CONTROLLER_BDADDR == TRUE)
    776                 if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE)
    777                     break;
    778 #else
    779                 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
    780                     break;
    781 #endif
    782                 /* fall through intentionally */
    783             case HW_CFG_SET_BD_ADDR:
    784                 ALOGI("vendor lib fwcfg completed");
    785                 bt_vendor_cbacks->dealloc(p_buf);
    786                 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
    787 
    788                 hw_cfg_cb.state = 0;
    789 
    790                 if (hw_cfg_cb.fw_fd != -1)
    791                 {
    792                     close(hw_cfg_cb.fw_fd);
    793                     hw_cfg_cb.fw_fd = -1;
    794                 }
    795 
    796                 is_proceeding = TRUE;
    797                 break;
    798 
    799 #if (USE_CONTROLLER_BDADDR == TRUE)
    800             case HW_CFG_READ_BD_ADDR:
    801                 p_tmp = (char *) (p_evt_buf + 1) + \
    802                          HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY;
    803 
    804                 if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0)
    805                 {
    806                     // Controller does not have a valid OTP BDADDR!
    807                     // Set the BTIF initial BDADDR instead.
    808                     if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
    809                         break;
    810                 }
    811                 else
    812                 {
    813                     ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X",
    814                         *(p_tmp+5), *(p_tmp+4), *(p_tmp+3),
    815                         *(p_tmp+2), *(p_tmp+1), *p_tmp);
    816                 }
    817 
    818                 ALOGI("vendor lib fwcfg completed");
    819                 bt_vendor_cbacks->dealloc(p_buf);
    820                 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
    821 
    822                 hw_cfg_cb.state = 0;
    823 
    824                 if (hw_cfg_cb.fw_fd != -1)
    825                 {
    826                     close(hw_cfg_cb.fw_fd);
    827                     hw_cfg_cb.fw_fd = -1;
    828                 }
    829 
    830                 is_proceeding = TRUE;
    831                 break;
    832 #endif // (USE_CONTROLLER_BDADDR == TRUE)
    833         } // switch(hw_cfg_cb.state)
    834     } // if (p_buf != NULL)
    835 
    836     /* Free the RX event buffer */
    837     if (bt_vendor_cbacks)
    838         bt_vendor_cbacks->dealloc(p_evt_buf);
    839 
    840     if (is_proceeding == FALSE)
    841     {
    842         ALOGE("vendor lib fwcfg aborted!!!");
    843         if (bt_vendor_cbacks)
    844         {
    845             if (p_buf != NULL)
    846                 bt_vendor_cbacks->dealloc(p_buf);
    847 
    848             bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
    849         }
    850 
    851         if (hw_cfg_cb.fw_fd != -1)
    852         {
    853             close(hw_cfg_cb.fw_fd);
    854             hw_cfg_cb.fw_fd = -1;
    855         }
    856 
    857         hw_cfg_cb.state = 0;
    858     }
    859 }
    860 
    861 /******************************************************************************
    862 **   LPM Static Functions
    863 ******************************************************************************/
    864 
    865 /*******************************************************************************
    866 **
    867 ** Function         hw_lpm_ctrl_cback
    868 **
    869 ** Description      Callback function for lpm enable/disable rquest
    870 **
    871 ** Returns          None
    872 **
    873 *******************************************************************************/
    874 void hw_lpm_ctrl_cback(void *p_mem)
    875 {
    876     HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
    877     bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL;
    878 
    879     if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0)
    880     {
    881         status = BT_VND_OP_RESULT_SUCCESS;
    882     }
    883 
    884     if (bt_vendor_cbacks)
    885     {
    886         bt_vendor_cbacks->lpm_cb(status);
    887         bt_vendor_cbacks->dealloc(p_evt_buf);
    888     }
    889 }
    890 
    891 
    892 #if (SCO_CFG_INCLUDED == TRUE)
    893 /*****************************************************************************
    894 **   SCO Configuration Static Functions
    895 *****************************************************************************/
    896 
    897 /*******************************************************************************
    898 **
    899 ** Function         hw_sco_cfg_cback
    900 **
    901 ** Description      Callback function for SCO configuration rquest
    902 **
    903 ** Returns          None
    904 **
    905 *******************************************************************************/
    906 void hw_sco_cfg_cback(void *p_mem)
    907 {
    908     HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
    909     uint8_t     *p;
    910     uint16_t    opcode;
    911     HC_BT_HDR  *p_buf=NULL;
    912 
    913     p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
    914     STREAM_TO_UINT16(opcode,p);
    915 
    916     /* Free the RX event buffer */
    917     if (bt_vendor_cbacks)
    918         bt_vendor_cbacks->dealloc(p_evt_buf);
    919 
    920 #if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
    921     if (opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM)
    922     {
    923         uint8_t ret = FALSE;
    924 
    925         /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */
    926         if (bt_vendor_cbacks)
    927             p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
    928                                                 HCI_CMD_PREAMBLE_SIZE + \
    929                                                 PCM_DATA_FORMAT_PARAM_SIZE);
    930         if (p_buf)
    931         {
    932             p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
    933             p_buf->offset = 0;
    934             p_buf->layer_specific = 0;
    935             p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE;
    936 
    937             p = (uint8_t *) (p_buf + 1);
    938             UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM);
    939             *p++ = PCM_DATA_FORMAT_PARAM_SIZE;
    940             memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE);
    941 
    942             if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,\
    943                                            p_buf, hw_sco_cfg_cback)) == FALSE)
    944             {
    945                 bt_vendor_cbacks->dealloc(p_buf);
    946             }
    947             else
    948                 return;
    949         }
    950     }
    951 #endif  // !SCO_USE_I2S_INTERFACE
    952 
    953 if (bt_vendor_cbacks)
    954     bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
    955 }
    956 #endif // SCO_CFG_INCLUDED
    957 
    958 /*****************************************************************************
    959 **   Hardware Configuration Interface Functions
    960 *****************************************************************************/
    961 
    962 
    963 /*******************************************************************************
    964 **
    965 ** Function        hw_config_start
    966 **
    967 ** Description     Kick off controller initialization process
    968 **
    969 ** Returns         None
    970 **
    971 *******************************************************************************/
    972 void hw_config_start(void)
    973 {
    974     HC_BT_HDR  *p_buf = NULL;
    975     uint8_t     *p;
    976 
    977     hw_cfg_cb.state = 0;
    978     hw_cfg_cb.fw_fd = -1;
    979     hw_cfg_cb.f_set_baud_2 = FALSE;
    980 
    981     /* Start from sending HCI_RESET */
    982 
    983     if (bt_vendor_cbacks)
    984     {
    985         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
    986                                                        HCI_CMD_PREAMBLE_SIZE);
    987     }
    988 
    989     if (p_buf)
    990     {
    991         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
    992         p_buf->offset = 0;
    993         p_buf->layer_specific = 0;
    994         p_buf->len = HCI_CMD_PREAMBLE_SIZE;
    995 
    996         p = (uint8_t *) (p_buf + 1);
    997         UINT16_TO_STREAM(p, HCI_RESET);
    998         *p = 0; /* parameter length */
    999 
   1000         hw_cfg_cb.state = HW_CFG_START;
   1001 
   1002         bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback);
   1003     }
   1004     else
   1005     {
   1006         if (bt_vendor_cbacks)
   1007         {
   1008             ALOGE("vendor lib fw conf aborted [no buffer]");
   1009             bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
   1010         }
   1011     }
   1012 }
   1013 
   1014 /*******************************************************************************
   1015 **
   1016 ** Function        hw_lpm_enable
   1017 **
   1018 ** Description     Enalbe/Disable LPM
   1019 **
   1020 ** Returns         TRUE/FALSE
   1021 **
   1022 *******************************************************************************/
   1023 uint8_t hw_lpm_enable(uint8_t turn_on)
   1024 {
   1025     HC_BT_HDR  *p_buf = NULL;
   1026     uint8_t     *p;
   1027     uint8_t     ret = FALSE;
   1028 
   1029     if (bt_vendor_cbacks)
   1030         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
   1031                                                        HCI_CMD_PREAMBLE_SIZE + \
   1032                                                        LPM_CMD_PARAM_SIZE);
   1033 
   1034     if (p_buf)
   1035     {
   1036         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
   1037         p_buf->offset = 0;
   1038         p_buf->layer_specific = 0;
   1039         p_buf->len = HCI_CMD_PREAMBLE_SIZE + LPM_CMD_PARAM_SIZE;
   1040 
   1041         p = (uint8_t *) (p_buf + 1);
   1042         UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE);
   1043         *p++ = LPM_CMD_PARAM_SIZE; /* parameter length */
   1044 
   1045         if (turn_on)
   1046         {
   1047             memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE);
   1048             upio_set(UPIO_LPM_MODE, UPIO_ASSERT, 0);
   1049         }
   1050         else
   1051         {
   1052             memset(p, 0, LPM_CMD_PARAM_SIZE);
   1053             upio_set(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
   1054         }
   1055 
   1056         if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \
   1057                                         hw_lpm_ctrl_cback)) == FALSE)
   1058         {
   1059             bt_vendor_cbacks->dealloc(p_buf);
   1060         }
   1061     }
   1062 
   1063     if ((ret == FALSE) && bt_vendor_cbacks)
   1064         bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL);
   1065 
   1066     return ret;
   1067 }
   1068 
   1069 /*******************************************************************************
   1070 **
   1071 ** Function        hw_lpm_get_idle_timeout
   1072 **
   1073 ** Description     Calculate idle time based on host stack idle threshold
   1074 **
   1075 ** Returns         idle timeout value
   1076 **
   1077 *******************************************************************************/
   1078 uint32_t hw_lpm_get_idle_timeout(void)
   1079 {
   1080     uint32_t timeout_ms;
   1081 
   1082     /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of
   1083      * host stack idle threshold (in 300ms/25ms)
   1084      */
   1085     timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold \
   1086                             * LPM_IDLE_TIMEOUT_MULTIPLE;
   1087 
   1088     if (strstr(hw_cfg_cb.local_chip_name, "BCM4325") != NULL)
   1089         timeout_ms *= 25; // 12.5 or 25 ?
   1090     else
   1091         timeout_ms *= 300;
   1092 
   1093     return timeout_ms;
   1094 }
   1095 
   1096 /*******************************************************************************
   1097 **
   1098 ** Function        hw_lpm_set_wake_state
   1099 **
   1100 ** Description     Assert/Deassert BT_WAKE
   1101 **
   1102 ** Returns         None
   1103 **
   1104 *******************************************************************************/
   1105 void hw_lpm_set_wake_state(uint8_t wake_assert)
   1106 {
   1107     uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT;
   1108 
   1109     upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity);
   1110 }
   1111 
   1112 #if (SCO_CFG_INCLUDED == TRUE)
   1113 /*******************************************************************************
   1114 **
   1115 ** Function         hw_sco_config
   1116 **
   1117 ** Description      Configure SCO related hardware settings
   1118 **
   1119 ** Returns          None
   1120 **
   1121 *******************************************************************************/
   1122 void hw_sco_config(void)
   1123 {
   1124     HC_BT_HDR  *p_buf = NULL;
   1125     uint8_t     *p, ret;
   1126 
   1127 #if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
   1128     uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE;
   1129 #else
   1130     uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
   1131 #endif
   1132 
   1133     if (bt_vendor_cbacks)
   1134         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE+cmd_u16);
   1135 
   1136     if (p_buf)
   1137     {
   1138         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
   1139         p_buf->offset = 0;
   1140         p_buf->layer_specific = 0;
   1141         p_buf->len = cmd_u16;
   1142 
   1143         p = (uint8_t *) (p_buf + 1);
   1144 #if (!defined(SCO_USE_I2S_INTERFACE) || (SCO_USE_I2S_INTERFACE == FALSE))
   1145         UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM);
   1146         *p++ = SCO_PCM_PARAM_SIZE;
   1147         memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE);
   1148         cmd_u16 = HCI_VSC_WRITE_SCO_PCM_INT_PARAM;
   1149         ALOGI("SCO PCM configure {%d, %d, %d, %d, %d}",
   1150            bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3], \
   1151            bt_sco_param[4]);
   1152 
   1153 #else
   1154         UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
   1155         *p++ = SCO_I2SPCM_PARAM_SIZE;
   1156         memcpy(p, &bt_sco_param, SCO_I2SPCM_PARAM_SIZE);
   1157         cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
   1158         ALOGI("SCO over I2SPCM interface {%d, %d, %d, %d}",
   1159            bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3]);
   1160 #endif
   1161 
   1162         if ((ret=bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_cfg_cback)) \
   1163              == FALSE)
   1164         {
   1165             bt_vendor_cbacks->dealloc(p_buf);
   1166         }
   1167         else
   1168             return;
   1169     }
   1170 
   1171     if (bt_vendor_cbacks)
   1172     {
   1173         ALOGE("vendor lib scocfg aborted");
   1174         bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_FAIL);
   1175     }
   1176 }
   1177 #endif  // SCO_CFG_INCLUDED
   1178 
   1179 /*******************************************************************************
   1180 **
   1181 ** Function        hw_set_patch_file_path
   1182 **
   1183 ** Description     Set the location of firmware patch file
   1184 **
   1185 ** Returns         0 : Success
   1186 **                 Otherwise : Fail
   1187 **
   1188 *******************************************************************************/
   1189 int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param)
   1190 {
   1191 
   1192     strcpy(fw_patchfile_path, p_conf_value);
   1193 
   1194     return 0;
   1195 }
   1196 
   1197 /*******************************************************************************
   1198 **
   1199 ** Function        hw_set_patch_file_name
   1200 **
   1201 ** Description     Give the specific firmware patch filename
   1202 **
   1203 ** Returns         0 : Success
   1204 **                 Otherwise : Fail
   1205 **
   1206 *******************************************************************************/
   1207 int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param)
   1208 {
   1209 
   1210     strcpy(fw_patchfile_name, p_conf_value);
   1211 
   1212     return 0;
   1213 }
   1214 
   1215 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
   1216 /*******************************************************************************
   1217 **
   1218 ** Function        hw_set_patch_settlement_delay
   1219 **
   1220 ** Description     Give the specific firmware patch settlement time in milliseconds
   1221 **
   1222 ** Returns         0 : Success
   1223 **                 Otherwise : Fail
   1224 **
   1225 *******************************************************************************/
   1226 int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param)
   1227 {
   1228     fw_patch_settlement_delay = atoi(p_conf_value);
   1229 
   1230     return 0;
   1231 }
   1232 #endif  //VENDOR_LIB_RUNTIME_TUNING_ENABLED
   1233 
   1234 /*****************************************************************************
   1235 **   Sample Codes Section
   1236 *****************************************************************************/
   1237 
   1238 #if (HW_END_WITH_HCI_RESET == TRUE)
   1239 /*******************************************************************************
   1240 **
   1241 ** Function         hw_epilog_cback
   1242 **
   1243 ** Description      Callback function for Command Complete Events from HCI
   1244 **                  commands sent in epilog process.
   1245 **
   1246 ** Returns          None
   1247 **
   1248 *******************************************************************************/
   1249 void hw_epilog_cback(void *p_mem)
   1250 {
   1251     HC_BT_HDR   *p_evt_buf = (HC_BT_HDR *) p_mem;
   1252     uint8_t     *p, status;
   1253     uint16_t    opcode;
   1254 
   1255     status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
   1256     p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
   1257     STREAM_TO_UINT16(opcode,p);
   1258 
   1259     BTHWDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status);
   1260 
   1261     if (bt_vendor_cbacks)
   1262     {
   1263         /* Must free the RX event buffer */
   1264         bt_vendor_cbacks->dealloc(p_evt_buf);
   1265 
   1266         /* Once epilog process is done, must call epilog_cb callback
   1267            to notify caller */
   1268         bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
   1269     }
   1270 }
   1271 
   1272 /*******************************************************************************
   1273 **
   1274 ** Function         hw_epilog_process
   1275 **
   1276 ** Description      Sample implementation of epilog process
   1277 **
   1278 ** Returns          None
   1279 **
   1280 *******************************************************************************/
   1281 void hw_epilog_process(void)
   1282 {
   1283     HC_BT_HDR  *p_buf = NULL;
   1284     uint8_t     *p;
   1285 
   1286     BTHWDBG("hw_epilog_process");
   1287 
   1288     /* Sending a HCI_RESET */
   1289     if (bt_vendor_cbacks)
   1290     {
   1291         /* Must allocate command buffer via HC's alloc API */
   1292         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
   1293                                                        HCI_CMD_PREAMBLE_SIZE);
   1294     }
   1295 
   1296     if (p_buf)
   1297     {
   1298         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
   1299         p_buf->offset = 0;
   1300         p_buf->layer_specific = 0;
   1301         p_buf->len = HCI_CMD_PREAMBLE_SIZE;
   1302 
   1303         p = (uint8_t *) (p_buf + 1);
   1304         UINT16_TO_STREAM(p, HCI_RESET);
   1305         *p = 0; /* parameter length */
   1306 
   1307         /* Send command via HC's xmit_cb API */
   1308         bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback);
   1309     }
   1310     else
   1311     {
   1312         if (bt_vendor_cbacks)
   1313         {
   1314             ALOGE("vendor lib epilog process aborted [no buffer]");
   1315             bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL);
   1316         }
   1317     }
   1318 }
   1319 #endif // (HW_END_WITH_HCI_RESET == TRUE)
   1320