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