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 */ 115enum { 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 */ 130typedef 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 */ 139typedef 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 */ 156typedef struct { 157 const char *chipset_name; 158 const uint32_t delay_time; 159} fw_settlement_entry_t; 160 161 162/****************************************************************************** 163** Externs 164******************************************************************************/ 165 166void hw_config_cback(void *p_evt_buf); 167extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN]; 168 169 170/****************************************************************************** 171** Static variables 172******************************************************************************/ 173 174static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION; 175static char fw_patchfile_name[128] = { 0 }; 176#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) 177static int fw_patch_settlement_delay = -1; 178#endif 179 180static int wbs_sample_rate = SCO_WBS_SAMPLE_RATE; 181static bt_hw_cfg_cb_t hw_cfg_cb; 182 183static 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 */ 202static 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 211static 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 220static 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 */ 232static 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) 249static uint8_t sco_bus_interface = SCO_INTERFACE_I2S; 250#else 251static uint8_t sco_bus_interface = SCO_INTERFACE_PCM; 252#endif 253 254#define INVALID_SCO_CLOCK_RATE 0xFF 255static uint8_t sco_bus_clock_rate = INVALID_SCO_CLOCK_RATE; 256static uint8_t sco_bus_wbs_clock_rate = INVALID_SCO_CLOCK_RATE; 257 258/****************************************************************************** 259** Static functions 260******************************************************************************/ 261static void hw_sco_i2spcm_config(uint16_t codec); 262static 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*******************************************************************************/ 283uint32_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*******************************************************************************/ 329void 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*******************************************************************************/ 356uint8_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*******************************************************************************/ 405static 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*******************************************************************************/ 433static 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*******************************************************************************/ 552static 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*******************************************************************************/ 590static 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*******************************************************************************/ 617void 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*******************************************************************************/ 929void 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*******************************************************************************/ 961static 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*******************************************************************************/ 1071static 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*******************************************************************************/ 1087static 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*******************************************************************************/ 1110void 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*******************************************************************************/ 1161uint8_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*******************************************************************************/ 1216uint32_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*******************************************************************************/ 1244void 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*******************************************************************************/ 1261void 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 1311static 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*******************************************************************************/ 1335static 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*******************************************************************************/ 1399static 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*******************************************************************************/ 1476int 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 1488int 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*******************************************************************************/ 1503int 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*******************************************************************************/ 1521int 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*******************************************************************************/ 1540int 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*******************************************************************************/ 1563void 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*******************************************************************************/ 1595void 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