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 <stdbool.h>
     34 #include <sys/stat.h>
     35 #include <signal.h>
     36 #include <time.h>
     37 #include <errno.h>
     38 #include <fcntl.h>
     39 #include <dirent.h>
     40 #include <ctype.h>
     41 #include <cutils/properties.h>
     42 #include <stdlib.h>
     43 #include <string.h>
     44 #include <stdio.h>
     45 #include <unistd.h>
     46 #include "bt_hci_bdroid.h"
     47 #include "bt_vendor_brcm.h"
     48 #include "esco_parameters.h"
     49 #include "userial.h"
     50 #include "userial_vendor.h"
     51 #include "upio.h"
     52 
     53 /******************************************************************************
     54 **  Constants & Macros
     55 ******************************************************************************/
     56 
     57 #ifndef BTHW_DBG
     58 #define BTHW_DBG FALSE
     59 #endif
     60 
     61 #if (BTHW_DBG == TRUE)
     62 #define BTHWDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
     63 #else
     64 #define BTHWDBG(param, ...) {}
     65 #endif
     66 
     67 #define FW_PATCHFILE_EXTENSION      ".hcd"
     68 #define FW_PATCHFILE_EXTENSION_LEN  4
     69 #define FW_PATCHFILE_PATH_MAXLEN    248 /* Local_Name length of return of
     70                                            HCI_Read_Local_Name */
     71 
     72 #define HCI_CMD_MAX_LEN             258
     73 
     74 #define HCI_RESET                               0x0C03
     75 #define HCI_VSC_WRITE_UART_CLOCK_SETTING        0xFC45
     76 #define HCI_VSC_UPDATE_BAUDRATE                 0xFC18
     77 #define HCI_READ_LOCAL_NAME                     0x0C14
     78 #define HCI_VSC_DOWNLOAD_MINIDRV                0xFC2E
     79 #define HCI_VSC_WRITE_BD_ADDR                   0xFC01
     80 #define HCI_VSC_WRITE_SLEEP_MODE                0xFC27
     81 #define HCI_VSC_WRITE_SCO_PCM_INT_PARAM         0xFC1C
     82 #define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM     0xFC1E
     83 #define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM    0xFC6D
     84 #define HCI_VSC_ENABLE_WBS                      0xFC7E
     85 #define HCI_VSC_LAUNCH_RAM                      0xFC4E
     86 #define HCI_READ_LOCAL_BDADDR                   0x1009
     87 
     88 #define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE        5
     89 #define HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING      6
     90 #define HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY     6
     91 #define HCI_EVT_CMD_CMPL_OPCODE                 3
     92 #define LPM_CMD_PARAM_SIZE                      12
     93 #define UPDATE_BAUDRATE_CMD_PARAM_SIZE          6
     94 #define HCI_CMD_PREAMBLE_SIZE                   3
     95 #define HCD_REC_PAYLOAD_LEN_BYTE                2
     96 #define BD_ADDR_LEN                             6
     97 #define LOCAL_NAME_BUFFER_LEN                   32
     98 #define LOCAL_BDADDR_PATH_BUFFER_LEN            256
     99 
    100 #define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
    101 #define UINT8_TO_STREAM(p, u8)   {*(p)++ = (uint8_t)(u8);}
    102 #define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
    103 #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);}
    104 
    105 #define SCO_INTERFACE_PCM  0
    106 #define SCO_INTERFACE_I2S  1
    107 
    108 /* one byte is for enable/disable
    109       next 2 bytes are for codec type */
    110 #define SCO_CODEC_PARAM_SIZE                    3
    111 
    112 /******************************************************************************
    113 **  Local type definitions
    114 ******************************************************************************/
    115 
    116 /* Hardware Configuration State */
    117 enum {
    118     HW_CFG_START = 1,
    119     HW_CFG_SET_UART_CLOCK,
    120     HW_CFG_SET_UART_BAUD_1,
    121     HW_CFG_READ_LOCAL_NAME,
    122     HW_CFG_DL_MINIDRIVER,
    123     HW_CFG_DL_FW_PATCH,
    124     HW_CFG_SET_UART_BAUD_2,
    125     HW_CFG_SET_BD_ADDR
    126 #if (USE_CONTROLLER_BDADDR == TRUE)
    127     , HW_CFG_READ_BD_ADDR
    128 #endif
    129 };
    130 
    131 /* h/w config control block */
    132 typedef struct
    133 {
    134     uint8_t state;                          /* Hardware configuration state */
    135     int     fw_fd;                          /* FW patch file fd */
    136     uint8_t f_set_baud_2;                   /* Baud rate switch state */
    137     char    local_chip_name[LOCAL_NAME_BUFFER_LEN];
    138 } bt_hw_cfg_cb_t;
    139 
    140 /* low power mode parameters */
    141 typedef struct
    142 {
    143     uint8_t sleep_mode;                     /* 0(disable),1(UART),9(H5) */
    144     uint8_t host_stack_idle_threshold;      /* Unit scale 300ms/25ms */
    145     uint8_t host_controller_idle_threshold; /* Unit scale 300ms/25ms */
    146     uint8_t bt_wake_polarity;               /* 0=Active Low, 1= Active High */
    147     uint8_t host_wake_polarity;             /* 0=Active Low, 1= Active High */
    148     uint8_t allow_host_sleep_during_sco;
    149     uint8_t combine_sleep_mode_and_lpm;
    150     uint8_t enable_uart_txd_tri_state;      /* UART_TXD Tri-State */
    151     uint8_t sleep_guard_time;               /* sleep guard time in 12.5ms */
    152     uint8_t wakeup_guard_time;              /* wakeup guard time in 12.5ms */
    153     uint8_t txd_config;                     /* TXD is high in sleep state */
    154     uint8_t pulsed_host_wake;               /* pulsed host wake if mode = 1 */
    155 } bt_lpm_param_t;
    156 
    157 /* Firmware re-launch settlement time */
    158 typedef struct {
    159     const char *chipset_name;
    160     const uint32_t delay_time;
    161 } fw_settlement_entry_t;
    162 
    163 
    164 /******************************************************************************
    165 **  Externs
    166 ******************************************************************************/
    167 
    168 void hw_config_cback(void *p_evt_buf);
    169 extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN];
    170 
    171 
    172 /******************************************************************************
    173 **  Static variables
    174 ******************************************************************************/
    175 
    176 static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION;
    177 static char fw_patchfile_name[128] = { 0 };
    178 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
    179 static int fw_patch_settlement_delay = -1;
    180 #endif
    181 
    182 static int wbs_sample_rate = SCO_WBS_SAMPLE_RATE;
    183 static bt_hw_cfg_cb_t hw_cfg_cb;
    184 
    185 static bt_lpm_param_t lpm_param =
    186 {
    187     LPM_SLEEP_MODE,
    188     LPM_IDLE_THRESHOLD,
    189     LPM_HC_IDLE_THRESHOLD,
    190     LPM_BT_WAKE_POLARITY,
    191     LPM_HOST_WAKE_POLARITY,
    192     LPM_ALLOW_HOST_SLEEP_DURING_SCO,
    193     LPM_COMBINE_SLEEP_MODE_AND_LPM,
    194     LPM_ENABLE_UART_TXD_TRI_STATE,
    195     0,  /* not applicable */
    196     0,  /* not applicable */
    197     0,  /* not applicable */
    198     LPM_PULSED_HOST_WAKE
    199 };
    200 
    201 /* need to update the bt_sco_i2spcm_param as well
    202    bt_sco_i2spcm_param will be used for WBS setting
    203    update the bt_sco_param and bt_sco_i2spcm_param */
    204 static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] =
    205 {
    206     SCO_PCM_ROUTING,
    207     SCO_PCM_IF_CLOCK_RATE,
    208     SCO_PCM_IF_FRAME_TYPE,
    209     SCO_PCM_IF_SYNC_MODE,
    210     SCO_PCM_IF_CLOCK_MODE
    211 };
    212 
    213 static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] =
    214 {
    215     PCM_DATA_FMT_SHIFT_MODE,
    216     PCM_DATA_FMT_FILL_BITS,
    217     PCM_DATA_FMT_FILL_METHOD,
    218     PCM_DATA_FMT_FILL_NUM,
    219     PCM_DATA_FMT_JUSTIFY_MODE
    220 };
    221 
    222 static uint8_t bt_sco_i2spcm_param[SCO_I2SPCM_PARAM_SIZE] =
    223 {
    224     SCO_I2SPCM_IF_MODE,
    225     SCO_I2SPCM_IF_ROLE,
    226     SCO_I2SPCM_IF_SAMPLE_RATE,
    227     SCO_I2SPCM_IF_CLOCK_RATE
    228 };
    229 
    230 /*
    231  * The look-up table of recommended firmware settlement delay (milliseconds) on
    232  * known chipsets.
    233  */
    234 static const fw_settlement_entry_t fw_settlement_table[] = {
    235     {"BCM43241", 200},
    236     {"BCM43341", 100},
    237     {(const char *) NULL, 100}  // Giving the generic fw settlement delay setting.
    238 };
    239 
    240 
    241 /*
    242  * NOTICE:
    243  *     If the platform plans to run I2S interface bus over I2S/PCM port of the
    244  *     BT Controller with the Host AP, explicitly set "SCO_USE_I2S_INTERFACE = TRUE"
    245  *     in the correspodning include/vnd_<target>.txt file.
    246  *     Otherwise, leave SCO_USE_I2S_INTERFACE undefined in the vnd_<target>.txt file.
    247  *     And, PCM interface will be set as the default bus format running over I2S/PCM
    248  *     port.
    249  */
    250 #if (defined(SCO_USE_I2S_INTERFACE) && SCO_USE_I2S_INTERFACE == TRUE)
    251 static uint8_t sco_bus_interface = SCO_INTERFACE_I2S;
    252 #else
    253 static uint8_t sco_bus_interface = SCO_INTERFACE_PCM;
    254 #endif
    255 
    256 #define INVALID_SCO_CLOCK_RATE  0xFF
    257 static uint8_t sco_bus_clock_rate = INVALID_SCO_CLOCK_RATE;
    258 static uint8_t sco_bus_wbs_clock_rate = INVALID_SCO_CLOCK_RATE;
    259 
    260 /******************************************************************************
    261 **  Static functions
    262 ******************************************************************************/
    263 static void hw_sco_i2spcm_config(uint16_t codec);
    264 static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec);
    265 
    266 /******************************************************************************
    267 **  Controller Initialization Static Functions
    268 ******************************************************************************/
    269 
    270 /*******************************************************************************
    271 **
    272 ** Function        look_up_fw_settlement_delay
    273 **
    274 ** Description     If FW_PATCH_SETTLEMENT_DELAY_MS has not been explicitly
    275 **                 re-defined in the platform specific build-time configuration
    276 **                 file, we will search into the look-up table for a
    277 **                 recommended firmware settlement delay value.
    278 **
    279 **                 Although the settlement time might be also related to board
    280 **                 configurations such as the crystal clocking speed.
    281 **
    282 ** Returns         Firmware settlement delay
    283 **
    284 *******************************************************************************/
    285 uint32_t look_up_fw_settlement_delay (void)
    286 {
    287     uint32_t ret_value;
    288     fw_settlement_entry_t *p_entry;
    289 
    290     if (FW_PATCH_SETTLEMENT_DELAY_MS > 0)
    291     {
    292         ret_value = FW_PATCH_SETTLEMENT_DELAY_MS;
    293     }
    294 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
    295     else if (fw_patch_settlement_delay >= 0)
    296     {
    297         ret_value = fw_patch_settlement_delay;
    298     }
    299 #endif
    300     else
    301     {
    302         p_entry = (fw_settlement_entry_t *)fw_settlement_table;
    303 
    304         while (p_entry->chipset_name != NULL)
    305         {
    306             if (strstr(hw_cfg_cb.local_chip_name, p_entry->chipset_name)!=NULL)
    307             {
    308                 break;
    309             }
    310 
    311             p_entry++;
    312         }
    313 
    314         ret_value = p_entry->delay_time;
    315     }
    316 
    317     BTHWDBG( "Settlement delay -- %d ms", ret_value);
    318 
    319     return (ret_value);
    320 }
    321 
    322 /*******************************************************************************
    323 **
    324 ** Function        ms_delay
    325 **
    326 ** Description     sleep unconditionally for timeout milliseconds
    327 **
    328 ** Returns         None
    329 **
    330 *******************************************************************************/
    331 void ms_delay (uint32_t timeout)
    332 {
    333     struct timespec delay;
    334     int err;
    335 
    336     if (timeout == 0)
    337         return;
    338 
    339     delay.tv_sec = timeout / 1000;
    340     delay.tv_nsec = 1000 * 1000 * (timeout%1000);
    341 
    342     /* [u]sleep can't be used because it uses SIGALRM */
    343     do {
    344         err = nanosleep(&delay, &delay);
    345     } while (err < 0 && errno ==EINTR);
    346 }
    347 
    348 /*******************************************************************************
    349 **
    350 ** Function        line_speed_to_userial_baud
    351 **
    352 ** Description     helper function converts line speed number into USERIAL baud
    353 **                 rate symbol
    354 **
    355 ** Returns         unit8_t (USERIAL baud symbol)
    356 **
    357 *******************************************************************************/
    358 uint8_t line_speed_to_userial_baud(uint32_t line_speed)
    359 {
    360     uint8_t baud;
    361 
    362     if (line_speed == 4000000)
    363         baud = USERIAL_BAUD_4M;
    364     else if (line_speed == 3000000)
    365         baud = USERIAL_BAUD_3M;
    366     else if (line_speed == 2000000)
    367         baud = USERIAL_BAUD_2M;
    368     else if (line_speed == 1000000)
    369         baud = USERIAL_BAUD_1M;
    370     else if (line_speed == 921600)
    371         baud = USERIAL_BAUD_921600;
    372     else if (line_speed == 460800)
    373         baud = USERIAL_BAUD_460800;
    374     else if (line_speed == 230400)
    375         baud = USERIAL_BAUD_230400;
    376     else if (line_speed == 115200)
    377         baud = USERIAL_BAUD_115200;
    378     else if (line_speed == 57600)
    379         baud = USERIAL_BAUD_57600;
    380     else if (line_speed == 19200)
    381         baud = USERIAL_BAUD_19200;
    382     else if (line_speed == 9600)
    383         baud = USERIAL_BAUD_9600;
    384     else if (line_speed == 1200)
    385         baud = USERIAL_BAUD_1200;
    386     else if (line_speed == 600)
    387         baud = USERIAL_BAUD_600;
    388     else
    389     {
    390         ALOGE( "userial vendor: unsupported baud speed %d", line_speed);
    391         baud = USERIAL_BAUD_115200;
    392     }
    393 
    394     return baud;
    395 }
    396 
    397 
    398 /*******************************************************************************
    399 **
    400 ** Function         hw_strncmp
    401 **
    402 ** Description      Used to compare two strings in caseless
    403 **
    404 ** Returns          0: match, otherwise: not match
    405 **
    406 *******************************************************************************/
    407 static int hw_strncmp (const char *p_str1, const char *p_str2, const int len)
    408 {
    409     int i;
    410 
    411     if (!p_str1 || !p_str2)
    412         return (1);
    413 
    414     for (i = 0; i < len; i++)
    415     {
    416         if (toupper(p_str1[i]) != toupper(p_str2[i]))
    417             return (i+1);
    418     }
    419 
    420     return 0;
    421 }
    422 
    423 /*******************************************************************************
    424 **
    425 ** Function         hw_config_findpatch
    426 **
    427 ** Description      Search for a proper firmware patch file
    428 **                  The selected firmware patch file name with full path
    429 **                  will be stored in the input string parameter, i.e.
    430 **                  p_chip_id_str, when returns.
    431 **
    432 ** Returns          TRUE when found the target patch file, otherwise FALSE
    433 **
    434 *******************************************************************************/
    435 static uint8_t hw_config_findpatch(char *p_chip_id_str)
    436 {
    437     DIR *dirp;
    438     struct dirent *dp;
    439     int filenamelen;
    440     uint8_t retval = FALSE;
    441 
    442     BTHWDBG("Target name = [%s]", p_chip_id_str);
    443 
    444     if (strlen(fw_patchfile_name)> 0)
    445     {
    446         /* If specific filepath and filename have been given in run-time
    447          * configuration /etc/bluetooth/bt_vendor.conf file, we will use them
    448          * to concatenate the filename to open rather than searching a file
    449          * matching to chipset name in the fw_patchfile_path folder.
    450          */
    451         sprintf(p_chip_id_str, "%s", fw_patchfile_path);
    452         if (fw_patchfile_path[strlen(fw_patchfile_path)- 1] != '/')
    453         {
    454             strcat(p_chip_id_str, "/");
    455         }
    456         strcat(p_chip_id_str, fw_patchfile_name);
    457 
    458         ALOGI("FW patchfile: %s", p_chip_id_str);
    459         return TRUE;
    460     }
    461 
    462     if ((dirp = opendir(fw_patchfile_path)) != NULL)
    463     {
    464         /* Fetch next filename in patchfile directory */
    465         while ((dp = readdir(dirp)) != NULL)
    466         {
    467             /* Check if filename starts with chip-id name */
    468             if ((hw_strncmp(dp->d_name, p_chip_id_str, strlen(p_chip_id_str)) \
    469                 ) == 0)
    470             {
    471                 /* Check if it has .hcd extenstion */
    472                 filenamelen = strlen(dp->d_name);
    473                 if ((filenamelen >= FW_PATCHFILE_EXTENSION_LEN) &&
    474                     ((hw_strncmp(
    475                           &dp->d_name[filenamelen-FW_PATCHFILE_EXTENSION_LEN], \
    476                           FW_PATCHFILE_EXTENSION, \
    477                           FW_PATCHFILE_EXTENSION_LEN) \
    478                      ) == 0))
    479                 {
    480                     ALOGI("Found patchfile: %s/%s", \
    481                         fw_patchfile_path, dp->d_name);
    482 
    483                     /* Make sure length does not exceed maximum */
    484                     if ((filenamelen + strlen(fw_patchfile_path)) > \
    485                          FW_PATCHFILE_PATH_MAXLEN)
    486                     {
    487                         ALOGE("Invalid patchfile name (too long)");
    488                     }
    489                     else
    490                     {
    491                         memset(p_chip_id_str, 0, FW_PATCHFILE_PATH_MAXLEN);
    492                         /* Found patchfile. Store location and name */
    493                         strcpy(p_chip_id_str, fw_patchfile_path);
    494                         if (fw_patchfile_path[ \
    495                             strlen(fw_patchfile_path)- 1 \
    496                             ] != '/')
    497                         {
    498                             strcat(p_chip_id_str, "/");
    499                         }
    500                         strcat(p_chip_id_str, dp->d_name);
    501                         retval = TRUE;
    502                     }
    503                     break;
    504                 }
    505             }
    506         }
    507 
    508         closedir(dirp);
    509 
    510         if (retval == FALSE)
    511         {
    512             /* Try again chip name without revision info */
    513 
    514             int len = strlen(p_chip_id_str);
    515             char *p = p_chip_id_str + len - 1;
    516 
    517             /* Scan backward and look for the first alphabet
    518                which is not M or m
    519             */
    520             while (len > 3) // BCM****
    521             {
    522                 if ((isdigit(*p)==0) && (*p != 'M') && (*p != 'm'))
    523                     break;
    524 
    525                 p--;
    526                 len--;
    527             }
    528 
    529             if (len > 3)
    530             {
    531                 *p = 0;
    532                 retval = hw_config_findpatch(p_chip_id_str);
    533             }
    534         }
    535     }
    536     else
    537     {
    538         ALOGE("Could not open %s", fw_patchfile_path);
    539     }
    540 
    541     return (retval);
    542 }
    543 
    544 /*******************************************************************************
    545 **
    546 ** Function         hw_config_set_bdaddr
    547 **
    548 ** Description      Program controller's Bluetooth Device Address
    549 **
    550 ** Returns          TRUE, if valid address is sent
    551 **                  FALSE, otherwise
    552 **
    553 *******************************************************************************/
    554 static uint8_t hw_config_set_bdaddr(HC_BT_HDR *p_buf)
    555 {
    556     uint8_t retval = FALSE;
    557     uint8_t *p = (uint8_t *) (p_buf + 1);
    558 
    559     ALOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X",
    560         vnd_local_bd_addr[0], vnd_local_bd_addr[1], vnd_local_bd_addr[2],
    561         vnd_local_bd_addr[3], vnd_local_bd_addr[4], vnd_local_bd_addr[5]);
    562 
    563     UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR);
    564     *p++ = BD_ADDR_LEN; /* parameter length */
    565     *p++ = vnd_local_bd_addr[5];
    566     *p++ = vnd_local_bd_addr[4];
    567     *p++ = vnd_local_bd_addr[3];
    568     *p++ = vnd_local_bd_addr[2];
    569     *p++ = vnd_local_bd_addr[1];
    570     *p = vnd_local_bd_addr[0];
    571 
    572     p_buf->len = HCI_CMD_PREAMBLE_SIZE + BD_ADDR_LEN;
    573     hw_cfg_cb.state = HW_CFG_SET_BD_ADDR;
    574 
    575     retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_BD_ADDR, p_buf, \
    576                                  hw_config_cback);
    577 
    578     return (retval);
    579 }
    580 
    581 #if (USE_CONTROLLER_BDADDR == TRUE)
    582 /*******************************************************************************
    583 **
    584 ** Function         hw_config_read_bdaddr
    585 **
    586 ** Description      Read controller's Bluetooth Device Address
    587 **
    588 ** Returns          TRUE, if valid address is sent
    589 **                  FALSE, otherwise
    590 **
    591 *******************************************************************************/
    592 static uint8_t hw_config_read_bdaddr(HC_BT_HDR *p_buf)
    593 {
    594     uint8_t retval = FALSE;
    595     uint8_t *p = (uint8_t *) (p_buf + 1);
    596 
    597     UINT16_TO_STREAM(p, HCI_READ_LOCAL_BDADDR);
    598     *p = 0; /* parameter length */
    599 
    600     p_buf->len = HCI_CMD_PREAMBLE_SIZE;
    601     hw_cfg_cb.state = HW_CFG_READ_BD_ADDR;
    602 
    603     retval = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_BDADDR, p_buf, \
    604                                  hw_config_cback);
    605 
    606     return (retval);
    607 }
    608 #endif // (USE_CONTROLLER_BDADDR == TRUE)
    609 
    610 /*******************************************************************************
    611 **
    612 ** Function         hw_config_cback
    613 **
    614 ** Description      Callback function for controller configuration
    615 **
    616 ** Returns          None
    617 **
    618 *******************************************************************************/
    619 void hw_config_cback(void *p_mem)
    620 {
    621     HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
    622     char        *p_name, *p_tmp;
    623     uint8_t     *p, status;
    624     uint16_t    opcode;
    625     HC_BT_HDR  *p_buf=NULL;
    626     uint8_t     is_proceeding = FALSE;
    627     int         i;
    628     int         delay=100;
    629 #if (USE_CONTROLLER_BDADDR == TRUE)
    630     const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
    631 #endif
    632 
    633     status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
    634     p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
    635     STREAM_TO_UINT16(opcode,p);
    636 
    637     /* Ask a new buffer big enough to hold any HCI commands sent in here */
    638     if ((status == 0) && bt_vendor_cbacks)
    639         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
    640                                                        HCI_CMD_MAX_LEN);
    641 
    642     if (p_buf != NULL)
    643     {
    644         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
    645         p_buf->offset = 0;
    646         p_buf->len = 0;
    647         p_buf->layer_specific = 0;
    648 
    649         p = (uint8_t *) (p_buf + 1);
    650 
    651         switch (hw_cfg_cb.state)
    652         {
    653             case HW_CFG_SET_UART_BAUD_1:
    654                 /* update baud rate of host's UART port */
    655                 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
    656                 userial_vendor_set_baud( \
    657                     line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
    658                 );
    659 
    660                 /* read local name */
    661                 UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME);
    662                 *p = 0; /* parameter length */
    663 
    664                 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
    665                 hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME;
    666 
    667                 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \
    668                                                     p_buf, hw_config_cback);
    669                 break;
    670 
    671             case HW_CFG_READ_LOCAL_NAME:
    672                 p_tmp = p_name = (char *) (p_evt_buf + 1) + \
    673                          HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING;
    674 
    675                 for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++)
    676                     *(p_name+i) = toupper(*(p_name+i));
    677 
    678                 if ((p_name = strstr(p_name, "BCM")) != NULL)
    679                 {
    680                     strncpy(hw_cfg_cb.local_chip_name, p_name, \
    681                             LOCAL_NAME_BUFFER_LEN-1);
    682                 }
    683 #ifdef USE_BLUETOOTH_BCM4343
    684                 else if ((p_name = strstr(p_tmp, "4343")) != NULL)
    685                 {
    686                     snprintf(hw_cfg_cb.local_chip_name,
    687                              LOCAL_NAME_BUFFER_LEN-1, "BCM%s", p_name);
    688                     strncpy(p_name, hw_cfg_cb.local_chip_name,
    689                             LOCAL_NAME_BUFFER_LEN-1);
    690                 }
    691 #endif
    692                 else
    693                 {
    694                     strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \
    695                             LOCAL_NAME_BUFFER_LEN-1);
    696                     p_name = p_tmp;
    697                 }
    698 
    699                 hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0;
    700 
    701                 BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name);
    702 
    703                 if ((status = hw_config_findpatch(p_name)) == TRUE)
    704                 {
    705                     if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1)
    706                     {
    707                         ALOGE("vendor lib preload failed to open [%s]", p_name);
    708                     }
    709                     else
    710                     {
    711                         /* vsc_download_minidriver */
    712                         UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV);
    713                         *p = 0; /* parameter length */
    714 
    715                         p_buf->len = HCI_CMD_PREAMBLE_SIZE;
    716                         hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER;
    717 
    718                         is_proceeding = bt_vendor_cbacks->xmit_cb( \
    719                                             HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \
    720                                             hw_config_cback);
    721                     }
    722                 }
    723                 else
    724                 {
    725                     ALOGE( \
    726                     "vendor lib preload failed to locate firmware patch file" \
    727                     );
    728                 }
    729 
    730                 if (is_proceeding == FALSE)
    731                 {
    732                     is_proceeding = hw_config_set_bdaddr(p_buf);
    733                 }
    734                 break;
    735 
    736             case HW_CFG_DL_MINIDRIVER:
    737                 /* give time for placing firmware in download mode */
    738                 ms_delay(50);
    739                 hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
    740                 /* fall through intentionally */
    741             case HW_CFG_DL_FW_PATCH:
    742                 p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE);
    743                 if (p_buf->len > 0)
    744                 {
    745                     if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \
    746                         (opcode == HCI_VSC_LAUNCH_RAM))
    747                     {
    748                         ALOGW("firmware patch file might be altered!");
    749                     }
    750                     else
    751                     {
    752                         p_buf->len += read(hw_cfg_cb.fw_fd, \
    753                                            p+HCI_CMD_PREAMBLE_SIZE,\
    754                                            *(p+HCD_REC_PAYLOAD_LEN_BYTE));
    755                         STREAM_TO_UINT16(opcode,p);
    756                         is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \
    757                                                 p_buf, hw_config_cback);
    758                         break;
    759                     }
    760                 }
    761 
    762                 close(hw_cfg_cb.fw_fd);
    763                 hw_cfg_cb.fw_fd = -1;
    764 
    765                 /* Normally the firmware patch configuration file
    766                  * sets the new starting baud rate at 115200.
    767                  * So, we need update host's baud rate accordingly.
    768                  */
    769                 ALOGI("bt vendor lib: set UART baud 115200");
    770                 userial_vendor_set_baud(USERIAL_BAUD_115200);
    771 
    772                 /* Next, we would like to boost baud rate up again
    773                  * to desired working speed.
    774                  */
    775                 hw_cfg_cb.f_set_baud_2 = TRUE;
    776 
    777                 /* Check if we need to pause a few hundred milliseconds
    778                  * before sending down any HCI command.
    779                  */
    780                 delay = look_up_fw_settlement_delay();
    781                 ALOGI("Setting fw settlement delay to %d ", delay);
    782                 ms_delay(delay);
    783 
    784                 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
    785                 UINT16_TO_STREAM(p, HCI_RESET);
    786                 *p = 0; /* parameter length */
    787                 hw_cfg_cb.state = HW_CFG_START;
    788                 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback);
    789                 break;
    790 
    791             case HW_CFG_START:
    792                 if (UART_TARGET_BAUD_RATE > 3000000)
    793                 {
    794                     /* set UART clock to 48MHz */
    795                     UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING);
    796                     *p++ = 1; /* parameter length */
    797                     *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */
    798 
    799                     p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1;
    800                     hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK;
    801 
    802                     is_proceeding = bt_vendor_cbacks->xmit_cb( \
    803                                         HCI_VSC_WRITE_UART_CLOCK_SETTING, \
    804                                         p_buf, hw_config_cback);
    805                     break;
    806                 }
    807                 /* fall through intentionally */
    808             case HW_CFG_SET_UART_CLOCK:
    809                 /* set controller's UART baud rate to 3M */
    810                 UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
    811                 *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */
    812                 *p++ = 0; /* encoded baud rate */
    813                 *p++ = 0; /* use encoded form */
    814                 UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);
    815 
    816                 p_buf->len = HCI_CMD_PREAMBLE_SIZE + \
    817                              UPDATE_BAUDRATE_CMD_PARAM_SIZE;
    818                 hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \
    819                             HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1;
    820 
    821                 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \
    822                                                     p_buf, hw_config_cback);
    823                 break;
    824 
    825             case HW_CFG_SET_UART_BAUD_2:
    826                 /* update baud rate of host's UART port */
    827                 ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
    828                 userial_vendor_set_baud( \
    829                     line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
    830                 );
    831 
    832 #if (USE_CONTROLLER_BDADDR == TRUE)
    833                 if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE)
    834                     break;
    835 #else
    836                 if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
    837                     break;
    838 #endif
    839                 /* fall through intentionally */
    840             case HW_CFG_SET_BD_ADDR:
    841                 ALOGI("vendor lib fwcfg completed");
    842                 bt_vendor_cbacks->dealloc(p_buf);
    843                 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
    844 
    845                 hw_cfg_cb.state = 0;
    846 
    847                 if (hw_cfg_cb.fw_fd != -1)
    848                 {
    849                     close(hw_cfg_cb.fw_fd);
    850                     hw_cfg_cb.fw_fd = -1;
    851                 }
    852 
    853                 is_proceeding = TRUE;
    854                 break;
    855 
    856 #if (USE_CONTROLLER_BDADDR == TRUE)
    857             case HW_CFG_READ_BD_ADDR:
    858                 p_tmp = (char *) (p_evt_buf + 1) + \
    859                          HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY;
    860 
    861                 if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0)
    862                 {
    863                     // Controller does not have a valid OTP BDADDR!
    864                     // Set the BTIF initial BDADDR instead.
    865                     if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
    866                         break;
    867                 }
    868                 else
    869                 {
    870                     ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X",
    871                         *(p_tmp+5), *(p_tmp+4), *(p_tmp+3),
    872                         *(p_tmp+2), *(p_tmp+1), *p_tmp);
    873                 }
    874 
    875                 ALOGI("vendor lib fwcfg completed");
    876                 bt_vendor_cbacks->dealloc(p_buf);
    877                 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
    878 
    879                 hw_cfg_cb.state = 0;
    880 
    881                 if (hw_cfg_cb.fw_fd != -1)
    882                 {
    883                     close(hw_cfg_cb.fw_fd);
    884                     hw_cfg_cb.fw_fd = -1;
    885                 }
    886 
    887                 is_proceeding = TRUE;
    888                 break;
    889 #endif // (USE_CONTROLLER_BDADDR == TRUE)
    890         } // switch(hw_cfg_cb.state)
    891     } // if (p_buf != NULL)
    892 
    893     /* Free the RX event buffer */
    894     if (bt_vendor_cbacks)
    895         bt_vendor_cbacks->dealloc(p_evt_buf);
    896 
    897     if (is_proceeding == FALSE)
    898     {
    899         ALOGE("vendor lib fwcfg aborted!!!");
    900         if (bt_vendor_cbacks)
    901         {
    902             if (p_buf != NULL)
    903                 bt_vendor_cbacks->dealloc(p_buf);
    904 
    905             bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
    906         }
    907 
    908         if (hw_cfg_cb.fw_fd != -1)
    909         {
    910             close(hw_cfg_cb.fw_fd);
    911             hw_cfg_cb.fw_fd = -1;
    912         }
    913 
    914         hw_cfg_cb.state = 0;
    915     }
    916 }
    917 
    918 /******************************************************************************
    919 **   LPM Static Functions
    920 ******************************************************************************/
    921 
    922 /*******************************************************************************
    923 **
    924 ** Function         hw_lpm_ctrl_cback
    925 **
    926 ** Description      Callback function for lpm enable/disable rquest
    927 **
    928 ** Returns          None
    929 **
    930 *******************************************************************************/
    931 void hw_lpm_ctrl_cback(void *p_mem)
    932 {
    933     HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
    934     bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL;
    935 
    936     if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0)
    937     {
    938         status = BT_VND_OP_RESULT_SUCCESS;
    939     }
    940 
    941     if (bt_vendor_cbacks)
    942     {
    943         bt_vendor_cbacks->lpm_cb(status);
    944         bt_vendor_cbacks->dealloc(p_evt_buf);
    945     }
    946 }
    947 
    948 
    949 #if (SCO_CFG_INCLUDED == TRUE)
    950 /*****************************************************************************
    951 **   SCO Configuration Static Functions
    952 *****************************************************************************/
    953 
    954 /*******************************************************************************
    955 **
    956 ** Function         hw_sco_i2spcm_cfg_cback
    957 **
    958 ** Description      Callback function for SCO I2S/PCM configuration rquest
    959 **
    960 ** Returns          None
    961 **
    962 *******************************************************************************/
    963 static void hw_sco_i2spcm_cfg_cback(void *p_mem)
    964 {
    965     HC_BT_HDR   *p_evt_buf = (HC_BT_HDR *)p_mem;
    966     uint8_t     *p;
    967     uint16_t    opcode;
    968     HC_BT_HDR   *p_buf = NULL;
    969     bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL;
    970 
    971     p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
    972     STREAM_TO_UINT16(opcode,p);
    973 
    974     if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0)
    975     {
    976         status = BT_VND_OP_RESULT_SUCCESS;
    977     }
    978 
    979     /* Free the RX event buffer */
    980     if (bt_vendor_cbacks)
    981         bt_vendor_cbacks->dealloc(p_evt_buf);
    982 
    983     if (status == BT_VND_OP_RESULT_SUCCESS)
    984     {
    985         if ((opcode == HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM) &&
    986             (SCO_INTERFACE_PCM == sco_bus_interface))
    987         {
    988             uint8_t ret = FALSE;
    989 
    990             /* Ask a new buffer to hold WRITE_SCO_PCM_INT_PARAM command */
    991             if (bt_vendor_cbacks)
    992                 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
    993                         BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE);
    994             if (p_buf)
    995             {
    996                 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
    997                 p_buf->offset = 0;
    998                 p_buf->layer_specific = 0;
    999                 p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_PCM_PARAM_SIZE;
   1000                 p = (uint8_t *)(p_buf + 1);
   1001 
   1002                 /* do we need this VSC for I2S??? */
   1003                 UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM);
   1004                 *p++ = SCO_PCM_PARAM_SIZE;
   1005                 memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE);
   1006                 ALOGI("SCO PCM configure {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}",
   1007                         bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3],
   1008                         bt_sco_param[4]);
   1009                 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SCO_PCM_INT_PARAM, p_buf,
   1010                         hw_sco_i2spcm_cfg_cback)) == FALSE)
   1011                 {
   1012                     bt_vendor_cbacks->dealloc(p_buf);
   1013                 }
   1014                 else
   1015                     return;
   1016             }
   1017             status = BT_VND_OP_RESULT_FAIL;
   1018         }
   1019         else if ((opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM) &&
   1020                  (SCO_INTERFACE_PCM == sco_bus_interface))
   1021         {
   1022             uint8_t ret = FALSE;
   1023 
   1024             /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */
   1025             if (bt_vendor_cbacks)
   1026                 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
   1027                         BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE);
   1028             if (p_buf)
   1029             {
   1030                 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
   1031                 p_buf->offset = 0;
   1032                 p_buf->layer_specific = 0;
   1033                 p_buf->len = HCI_CMD_PREAMBLE_SIZE + PCM_DATA_FORMAT_PARAM_SIZE;
   1034 
   1035                 p = (uint8_t *)(p_buf + 1);
   1036                 UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM);
   1037                 *p++ = PCM_DATA_FORMAT_PARAM_SIZE;
   1038                 memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE);
   1039 
   1040                 ALOGI("SCO PCM data format {0x%x, 0x%x, 0x%x, 0x%x, 0x%x}",
   1041                         bt_pcm_data_fmt_param[0], bt_pcm_data_fmt_param[1],
   1042                         bt_pcm_data_fmt_param[2], bt_pcm_data_fmt_param[3],
   1043                         bt_pcm_data_fmt_param[4]);
   1044 
   1045                 if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,
   1046                         p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE)
   1047                 {
   1048                     bt_vendor_cbacks->dealloc(p_buf);
   1049                 }
   1050                 else
   1051                     return;
   1052             }
   1053             status = BT_VND_OP_RESULT_FAIL;
   1054         }
   1055     }
   1056 
   1057     ALOGI("sco I2S/PCM config result %d [0-Success, 1-Fail]", status);
   1058     if (bt_vendor_cbacks)
   1059     {
   1060         bt_vendor_cbacks->audio_state_cb(status);
   1061     }
   1062 }
   1063 
   1064 /*******************************************************************************
   1065 **
   1066 ** Function         hw_set_MSBC_codec_cback
   1067 **
   1068 ** Description      Callback function for setting WBS codec
   1069 **
   1070 ** Returns          None
   1071 **
   1072 *******************************************************************************/
   1073 static void hw_set_MSBC_codec_cback(void *p_mem)
   1074 {
   1075     /* whenever update the codec enable/disable, need to update I2SPCM */
   1076     ALOGI("SCO I2S interface change the sample rate to 16K");
   1077     hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_MSBC);
   1078 }
   1079 
   1080 /*******************************************************************************
   1081 **
   1082 ** Function         hw_set_CVSD_codec_cback
   1083 **
   1084 ** Description      Callback function for setting NBS codec
   1085 **
   1086 ** Returns          None
   1087 **
   1088 *******************************************************************************/
   1089 static void hw_set_CVSD_codec_cback(void *p_mem)
   1090 {
   1091     /* whenever update the codec enable/disable, need to update I2SPCM */
   1092     ALOGI("SCO I2S interface change the sample rate to 8K");
   1093     hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_CVSD);
   1094 }
   1095 
   1096 #endif // SCO_CFG_INCLUDED
   1097 
   1098 /*****************************************************************************
   1099 **   Hardware Configuration Interface Functions
   1100 *****************************************************************************/
   1101 
   1102 
   1103 /*******************************************************************************
   1104 **
   1105 ** Function        hw_config_start
   1106 **
   1107 ** Description     Kick off controller initialization process
   1108 **
   1109 ** Returns         None
   1110 **
   1111 *******************************************************************************/
   1112 void hw_config_start(void)
   1113 {
   1114     HC_BT_HDR  *p_buf = NULL;
   1115     uint8_t     *p;
   1116 
   1117     hw_cfg_cb.state = 0;
   1118     hw_cfg_cb.fw_fd = -1;
   1119     hw_cfg_cb.f_set_baud_2 = FALSE;
   1120 
   1121     /* Start from sending HCI_RESET */
   1122 
   1123     if (bt_vendor_cbacks)
   1124     {
   1125         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
   1126                                                        HCI_CMD_PREAMBLE_SIZE);
   1127     }
   1128 
   1129     if (p_buf)
   1130     {
   1131         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
   1132         p_buf->offset = 0;
   1133         p_buf->layer_specific = 0;
   1134         p_buf->len = HCI_CMD_PREAMBLE_SIZE;
   1135 
   1136         p = (uint8_t *) (p_buf + 1);
   1137         UINT16_TO_STREAM(p, HCI_RESET);
   1138         *p = 0; /* parameter length */
   1139 
   1140         hw_cfg_cb.state = HW_CFG_START;
   1141 
   1142         bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback);
   1143     }
   1144     else
   1145     {
   1146         if (bt_vendor_cbacks)
   1147         {
   1148             ALOGE("vendor lib fw conf aborted [no buffer]");
   1149             bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
   1150         }
   1151     }
   1152 }
   1153 
   1154 /*******************************************************************************
   1155 **
   1156 ** Function        hw_lpm_enable
   1157 **
   1158 ** Description     Enalbe/Disable LPM
   1159 **
   1160 ** Returns         TRUE/FALSE
   1161 **
   1162 *******************************************************************************/
   1163 uint8_t hw_lpm_enable(uint8_t turn_on)
   1164 {
   1165     HC_BT_HDR  *p_buf = NULL;
   1166     uint8_t     *p;
   1167     uint8_t     ret = FALSE;
   1168 
   1169     if (bt_vendor_cbacks)
   1170         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
   1171                                                        HCI_CMD_PREAMBLE_SIZE + \
   1172                                                        LPM_CMD_PARAM_SIZE);
   1173 
   1174     if (p_buf)
   1175     {
   1176         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
   1177         p_buf->offset = 0;
   1178         p_buf->layer_specific = 0;
   1179         p_buf->len = HCI_CMD_PREAMBLE_SIZE + LPM_CMD_PARAM_SIZE;
   1180 
   1181         p = (uint8_t *) (p_buf + 1);
   1182         UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE);
   1183         *p++ = LPM_CMD_PARAM_SIZE; /* parameter length */
   1184 
   1185         if (turn_on)
   1186         {
   1187             memcpy(p, &lpm_param, LPM_CMD_PARAM_SIZE);
   1188             upio_set(UPIO_LPM_MODE, UPIO_ASSERT, 0);
   1189         }
   1190         else
   1191         {
   1192             memset(p, 0, LPM_CMD_PARAM_SIZE);
   1193             upio_set(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
   1194         }
   1195 
   1196         if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_SLEEP_MODE, p_buf, \
   1197                                         hw_lpm_ctrl_cback)) == FALSE)
   1198         {
   1199             bt_vendor_cbacks->dealloc(p_buf);
   1200         }
   1201     }
   1202 
   1203     if ((ret == FALSE) && bt_vendor_cbacks)
   1204         bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL);
   1205 
   1206     return ret;
   1207 }
   1208 
   1209 /*******************************************************************************
   1210 **
   1211 ** Function        hw_lpm_get_idle_timeout
   1212 **
   1213 ** Description     Calculate idle time based on host stack idle threshold
   1214 **
   1215 ** Returns         idle timeout value
   1216 **
   1217 *******************************************************************************/
   1218 uint32_t hw_lpm_get_idle_timeout(void)
   1219 {
   1220     uint32_t timeout_ms;
   1221 
   1222     /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of
   1223      * host stack idle threshold (in 300ms/25ms)
   1224      */
   1225     timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold \
   1226                             * LPM_IDLE_TIMEOUT_MULTIPLE;
   1227     if (strstr(hw_cfg_cb.local_chip_name, "BCM4325") != NULL)
   1228         timeout_ms *= 25; // 12.5 or 25 ?
   1229     else if (strstr(hw_cfg_cb.local_chip_name, "BCM4358") != NULL)
   1230         timeout_ms *= 50;
   1231     else
   1232         timeout_ms *= 300;
   1233 
   1234     return timeout_ms;
   1235 }
   1236 
   1237 /*******************************************************************************
   1238 **
   1239 ** Function        hw_lpm_set_wake_state
   1240 **
   1241 ** Description     Assert/Deassert BT_WAKE
   1242 **
   1243 ** Returns         None
   1244 **
   1245 *******************************************************************************/
   1246 void hw_lpm_set_wake_state(uint8_t wake_assert)
   1247 {
   1248     uint8_t state = (wake_assert) ? UPIO_ASSERT : UPIO_DEASSERT;
   1249 
   1250     upio_set(UPIO_BT_WAKE, state, lpm_param.bt_wake_polarity);
   1251 }
   1252 
   1253 #if (SCO_CFG_INCLUDED == TRUE)
   1254 /*******************************************************************************
   1255 **
   1256 ** Function         hw_sco_config
   1257 **
   1258 ** Description      Configure SCO related hardware settings
   1259 **
   1260 ** Returns          None
   1261 **
   1262 *******************************************************************************/
   1263 void hw_sco_config(void)
   1264 {
   1265     if (SCO_INTERFACE_I2S == sco_bus_interface)
   1266     {
   1267         /* 'Enable' I2S mode */
   1268         bt_sco_i2spcm_param[0] = 1;
   1269 
   1270         /* set nbs clock rate as the value in SCO_I2SPCM_IF_CLOCK_RATE field */
   1271         sco_bus_clock_rate = bt_sco_i2spcm_param[3];
   1272     }
   1273     else
   1274     {
   1275         /* 'Disable' I2S mode */
   1276         bt_sco_i2spcm_param[0] = 0;
   1277 
   1278         /* set nbs clock rate as the value in SCO_PCM_IF_CLOCK_RATE field */
   1279         sco_bus_clock_rate = bt_sco_param[1];
   1280 
   1281         /* sync up clock mode setting */
   1282         bt_sco_i2spcm_param[1] = bt_sco_param[4];
   1283     }
   1284 
   1285     if (sco_bus_wbs_clock_rate == INVALID_SCO_CLOCK_RATE)
   1286     {
   1287         /* set default wbs clock rate */
   1288         sco_bus_wbs_clock_rate = SCO_I2SPCM_IF_CLOCK_RATE4WBS;
   1289 
   1290         if (sco_bus_wbs_clock_rate < sco_bus_clock_rate)
   1291             sco_bus_wbs_clock_rate = sco_bus_clock_rate;
   1292     }
   1293 
   1294     /*
   1295      *  To support I2S/PCM port multiplexing signals for sharing Bluetooth audio
   1296      *  and FM on the same PCM pins, we defer Bluetooth audio (SCO/eSCO)
   1297      *  configuration till SCO/eSCO is being established;
   1298      *  i.e. in hw_set_audio_state() call.
   1299      *  When configured as I2S only, Bluetooth audio configuration is executed
   1300      *  immediately with SCO_CODEC_CVSD by default.
   1301      */
   1302 
   1303     if (SCO_INTERFACE_I2S == sco_bus_interface) {
   1304         hw_sco_i2spcm_config(SCO_CODEC_CVSD);
   1305     }
   1306 
   1307     if (bt_vendor_cbacks)
   1308     {
   1309         bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
   1310     }
   1311 }
   1312 
   1313 static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec) {
   1314     HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
   1315     bool command_success = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0;
   1316 
   1317     /* Free the RX event buffer */
   1318     if (bt_vendor_cbacks)
   1319         bt_vendor_cbacks->dealloc(p_evt_buf);
   1320 
   1321     if (command_success)
   1322         hw_sco_i2spcm_config(codec);
   1323     else if (bt_vendor_cbacks)
   1324         bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL);
   1325 }
   1326 
   1327 
   1328 /*******************************************************************************
   1329 **
   1330 ** Function         hw_sco_i2spcm_config
   1331 **
   1332 ** Description      Configure SCO over I2S or PCM
   1333 **
   1334 ** Returns          None
   1335 **
   1336 *******************************************************************************/
   1337 static void hw_sco_i2spcm_config(uint16_t codec)
   1338 {
   1339     HC_BT_HDR *p_buf = NULL;
   1340     uint8_t *p, ret;
   1341     uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
   1342 
   1343     if (bt_vendor_cbacks)
   1344         p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + cmd_u16);
   1345 
   1346     if (p_buf)
   1347     {
   1348         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
   1349         p_buf->offset = 0;
   1350         p_buf->layer_specific = 0;
   1351         p_buf->len = cmd_u16;
   1352 
   1353         p = (uint8_t *)(p_buf + 1);
   1354 
   1355         UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
   1356         *p++ = SCO_I2SPCM_PARAM_SIZE;
   1357         if (codec == SCO_CODEC_CVSD)
   1358         {
   1359             bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE  8k */
   1360             bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
   1361         }
   1362         else if (codec == SCO_CODEC_MSBC)
   1363         {
   1364             bt_sco_i2spcm_param[2] = wbs_sample_rate; /* SCO_I2SPCM_IF_SAMPLE_RATE 16K */
   1365             bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_wbs_clock_rate;
   1366         }
   1367         else
   1368         {
   1369             bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE  8k */
   1370             bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
   1371             ALOGE("wrong codec is use in hw_sco_i2spcm_config, goes default NBS");
   1372         }
   1373         memcpy(p, &bt_sco_i2spcm_param, SCO_I2SPCM_PARAM_SIZE);
   1374         cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
   1375         ALOGI("I2SPCM config {0x%x, 0x%x, 0x%x, 0x%x}",
   1376                 bt_sco_i2spcm_param[0], bt_sco_i2spcm_param[1],
   1377                 bt_sco_i2spcm_param[2], bt_sco_i2spcm_param[3]);
   1378 
   1379         if ((ret = bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE)
   1380         {
   1381             bt_vendor_cbacks->dealloc(p_buf);
   1382         }
   1383         else
   1384             return;
   1385     }
   1386 
   1387     bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL);
   1388 }
   1389 
   1390 /*******************************************************************************
   1391 **
   1392 ** Function         hw_set_SCO_codec
   1393 **
   1394 ** Description      This functgion sends command to the controller to setup
   1395 **                              WBS/NBS codec for the upcoming eSCO connection.
   1396 **
   1397 ** Returns          -1 : Failed to send VSC
   1398 **                   0 : Success
   1399 **
   1400 *******************************************************************************/
   1401 static int hw_set_SCO_codec(uint16_t codec)
   1402 {
   1403     HC_BT_HDR   *p_buf = NULL;
   1404     uint8_t     *p;
   1405     uint8_t     ret;
   1406     int         ret_val = 0;
   1407     tINT_CMD_CBACK p_set_SCO_codec_cback;
   1408 
   1409     BTHWDBG( "hw_set_SCO_codec 0x%x", codec);
   1410 
   1411     if (bt_vendor_cbacks)
   1412         p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
   1413                 BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE);
   1414 
   1415     if (p_buf)
   1416     {
   1417         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
   1418         p_buf->offset = 0;
   1419         p_buf->layer_specific = 0;
   1420         p = (uint8_t *)(p_buf + 1);
   1421 
   1422         UINT16_TO_STREAM(p, HCI_VSC_ENABLE_WBS);
   1423 
   1424         if (codec == SCO_CODEC_MSBC)
   1425         {
   1426             /* Enable mSBC */
   1427             *p++ = SCO_CODEC_PARAM_SIZE; /* set the parameter size */
   1428             UINT8_TO_STREAM(p,1); /* enable */
   1429             UINT16_TO_STREAM(p, codec);
   1430 
   1431             /* set the totall size of this packet */
   1432             p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE;
   1433 
   1434             p_set_SCO_codec_cback = hw_set_MSBC_codec_cback;
   1435         }
   1436         else
   1437         {
   1438             /* Disable mSBC */
   1439             *p++ = (SCO_CODEC_PARAM_SIZE - 2); /* set the parameter size */
   1440             UINT8_TO_STREAM(p,0); /* disable */
   1441 
   1442             /* set the totall size of this packet */
   1443             p_buf->len = HCI_CMD_PREAMBLE_SIZE + SCO_CODEC_PARAM_SIZE - 2;
   1444 
   1445             p_set_SCO_codec_cback = hw_set_CVSD_codec_cback;
   1446             if ((codec != SCO_CODEC_CVSD) && (codec != SCO_CODEC_NONE))
   1447             {
   1448                 ALOGW("SCO codec setting is wrong: codec: 0x%x", codec);
   1449             }
   1450         }
   1451 
   1452         if ((ret = bt_vendor_cbacks->xmit_cb(HCI_VSC_ENABLE_WBS, p_buf, p_set_SCO_codec_cback))\
   1453               == FALSE)
   1454         {
   1455             bt_vendor_cbacks->dealloc(p_buf);
   1456             ret_val = -1;
   1457         }
   1458     }
   1459     else
   1460     {
   1461         ret_val = -1;
   1462     }
   1463 
   1464     return ret_val;
   1465 }
   1466 
   1467 /*******************************************************************************
   1468 **
   1469 ** Function         hw_set_audio_state
   1470 **
   1471 ** Description      This function configures audio base on provided audio state
   1472 **
   1473 ** Paramters        pointer to audio state structure
   1474 **
   1475 ** Returns          0: ok, -1: error
   1476 **
   1477 *******************************************************************************/
   1478 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state)
   1479 {
   1480     int ret_val = -1;
   1481 
   1482     if (!bt_vendor_cbacks)
   1483         return ret_val;
   1484 
   1485     ret_val = hw_set_SCO_codec(p_state->peer_codec);
   1486     return ret_val;
   1487 }
   1488 
   1489 #else  // SCO_CFG_INCLUDED
   1490 int hw_set_audio_state(bt_vendor_op_audio_state_t *p_state)
   1491 {
   1492     return -256;
   1493 }
   1494 #endif
   1495 /*******************************************************************************
   1496 **
   1497 ** Function        hw_set_patch_file_path
   1498 **
   1499 ** Description     Set the location of firmware patch file
   1500 **
   1501 ** Returns         0 : Success
   1502 **                 Otherwise : Fail
   1503 **
   1504 *******************************************************************************/
   1505 int hw_set_patch_file_path(char *p_conf_name, char *p_conf_value, int param)
   1506 {
   1507 
   1508     strcpy(fw_patchfile_path, p_conf_value);
   1509 
   1510     return 0;
   1511 }
   1512 
   1513 /*******************************************************************************
   1514 **
   1515 ** Function        hw_set_patch_file_name
   1516 **
   1517 ** Description     Give the specific firmware patch filename
   1518 **
   1519 ** Returns         0 : Success
   1520 **                 Otherwise : Fail
   1521 **
   1522 *******************************************************************************/
   1523 int hw_set_patch_file_name(char *p_conf_name, char *p_conf_value, int param)
   1524 {
   1525 
   1526     strcpy(fw_patchfile_name, p_conf_value);
   1527 
   1528     return 0;
   1529 }
   1530 
   1531 #if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
   1532 /*******************************************************************************
   1533 **
   1534 ** Function        hw_set_patch_settlement_delay
   1535 **
   1536 ** Description     Give the specific firmware patch settlement time in milliseconds
   1537 **
   1538 ** Returns         0 : Success
   1539 **                 Otherwise : Fail
   1540 **
   1541 *******************************************************************************/
   1542 int hw_set_patch_settlement_delay(char *p_conf_name, char *p_conf_value, int param)
   1543 {
   1544     fw_patch_settlement_delay = atoi(p_conf_value);
   1545 
   1546     return 0;
   1547 }
   1548 #endif  //VENDOR_LIB_RUNTIME_TUNING_ENABLED
   1549 
   1550 /*****************************************************************************
   1551 **   Sample Codes Section
   1552 *****************************************************************************/
   1553 
   1554 #if (HW_END_WITH_HCI_RESET == TRUE)
   1555 /*******************************************************************************
   1556 **
   1557 ** Function         hw_epilog_cback
   1558 **
   1559 ** Description      Callback function for Command Complete Events from HCI
   1560 **                  commands sent in epilog process.
   1561 **
   1562 ** Returns          None
   1563 **
   1564 *******************************************************************************/
   1565 void hw_epilog_cback(void *p_mem)
   1566 {
   1567     HC_BT_HDR   *p_evt_buf = (HC_BT_HDR *) p_mem;
   1568     uint8_t     *p, status;
   1569     uint16_t    opcode;
   1570 
   1571     status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
   1572     p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
   1573     STREAM_TO_UINT16(opcode,p);
   1574 
   1575     BTHWDBG("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status);
   1576 
   1577     if (bt_vendor_cbacks)
   1578     {
   1579         /* Must free the RX event buffer */
   1580         bt_vendor_cbacks->dealloc(p_evt_buf);
   1581 
   1582         /* Once epilog process is done, must call epilog_cb callback
   1583            to notify caller */
   1584         bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
   1585     }
   1586 }
   1587 
   1588 /*******************************************************************************
   1589 **
   1590 ** Function         hw_epilog_process
   1591 **
   1592 ** Description      Sample implementation of epilog process
   1593 **
   1594 ** Returns          None
   1595 **
   1596 *******************************************************************************/
   1597 void hw_epilog_process(void)
   1598 {
   1599     HC_BT_HDR  *p_buf = NULL;
   1600     uint8_t     *p;
   1601 
   1602     BTHWDBG("hw_epilog_process");
   1603 
   1604     /* Sending a HCI_RESET */
   1605     if (bt_vendor_cbacks)
   1606     {
   1607         /* Must allocate command buffer via HC's alloc API */
   1608         p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
   1609                                                        HCI_CMD_PREAMBLE_SIZE);
   1610     }
   1611 
   1612     if (p_buf)
   1613     {
   1614         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
   1615         p_buf->offset = 0;
   1616         p_buf->layer_specific = 0;
   1617         p_buf->len = HCI_CMD_PREAMBLE_SIZE;
   1618 
   1619         p = (uint8_t *) (p_buf + 1);
   1620         UINT16_TO_STREAM(p, HCI_RESET);
   1621         *p = 0; /* parameter length */
   1622 
   1623         /* Send command via HC's xmit_cb API */
   1624         bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback);
   1625     }
   1626     else
   1627     {
   1628         if (bt_vendor_cbacks)
   1629         {
   1630             ALOGE("vendor lib epilog process aborted [no buffer]");
   1631             bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL);
   1632         }
   1633     }
   1634 }
   1635 #endif // (HW_END_WITH_HCI_RESET == TRUE)
   1636