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