10b966c5eSopenharmony_ci/****************************************************************************** 20b966c5eSopenharmony_ci * 30b966c5eSopenharmony_ci * Copyright (C) 2009-2012 Broadcom Corporation 40b966c5eSopenharmony_ci * 50b966c5eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 60b966c5eSopenharmony_ci * you may not use this file except in compliance with the License. 70b966c5eSopenharmony_ci * You may obtain a copy of the License at: 80b966c5eSopenharmony_ci * 90b966c5eSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 100b966c5eSopenharmony_ci * 110b966c5eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 120b966c5eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 130b966c5eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 140b966c5eSopenharmony_ci * See the License for the specific language governing permissions and 150b966c5eSopenharmony_ci * limitations under the License. 160b966c5eSopenharmony_ci * 170b966c5eSopenharmony_ci ******************************************************************************/ 180b966c5eSopenharmony_ci 190b966c5eSopenharmony_ci/****************************************************************************** 200b966c5eSopenharmony_ci * 210b966c5eSopenharmony_ci * Filename: bt_vendor_brcm.c 220b966c5eSopenharmony_ci * 230b966c5eSopenharmony_ci * Description: Broadcom vendor specific library implementation 240b966c5eSopenharmony_ci * 250b966c5eSopenharmony_ci ******************************************************************************/ 260b966c5eSopenharmony_ci 270b966c5eSopenharmony_ci#define LOG_TAG "bt_vendor" 280b966c5eSopenharmony_ci 290b966c5eSopenharmony_ci#include <utils/Log.h> 300b966c5eSopenharmony_ci#include <string.h> 310b966c5eSopenharmony_ci#include "upio.h" 320b966c5eSopenharmony_ci#include "userial_vendor.h" 330b966c5eSopenharmony_ci#include "bt_vendor_brcm.h" 340b966c5eSopenharmony_ci 350b966c5eSopenharmony_ci#ifndef BTVND_DBG 360b966c5eSopenharmony_ci#define BTVND_DBG FALSE 370b966c5eSopenharmony_ci#endif 380b966c5eSopenharmony_ci 390b966c5eSopenharmony_ci#if (BTVND_DBG == TRUE) 400b966c5eSopenharmony_ci#define BTVNDDBG(param, ...) \ 410b966c5eSopenharmony_ci { \ 420b966c5eSopenharmony_ci HILOGD(param, ##__VA_ARGS__); \ 430b966c5eSopenharmony_ci } 440b966c5eSopenharmony_ci#else 450b966c5eSopenharmony_ci#define BTVNDDBG(param, ...) \ 460b966c5eSopenharmony_ci { \ 470b966c5eSopenharmony_ci HILOGD(param, ##__VA_ARGS__); \ 480b966c5eSopenharmony_ci } 490b966c5eSopenharmony_ci#endif 500b966c5eSopenharmony_ci 510b966c5eSopenharmony_ci/****************************************************************************** 520b966c5eSopenharmony_ci** Externs 530b966c5eSopenharmony_ci******************************************************************************/ 540b966c5eSopenharmony_ci 550b966c5eSopenharmony_civoid hw_config_start(void); 560b966c5eSopenharmony_ciuint8_t hw_lpm_enable(uint8_t turn_on); 570b966c5eSopenharmony_ciuint32_t hw_lpm_get_idle_timeout(void); 580b966c5eSopenharmony_civoid hw_lpm_set_wake_state(uint8_t wake_assert); 590b966c5eSopenharmony_ci#if (SCO_CFG_INCLUDED == TRUE) 600b966c5eSopenharmony_civoid hw_sco_config(void); 610b966c5eSopenharmony_ci#endif 620b966c5eSopenharmony_civoid vnd_load_conf(const char *p_path); 630b966c5eSopenharmony_ci#if (HW_END_WITH_HCI_RESET == TRUE) 640b966c5eSopenharmony_civoid hw_epilog_process(void); 650b966c5eSopenharmony_ci#endif 660b966c5eSopenharmony_ci 670b966c5eSopenharmony_ci/****************************************************************************** 680b966c5eSopenharmony_ci** Variables 690b966c5eSopenharmony_ci******************************************************************************/ 700b966c5eSopenharmony_ci 710b966c5eSopenharmony_cibt_vendor_callbacks_t *bt_vendor_cbacks = NULL; 720b966c5eSopenharmony_ciuint8_t vnd_local_bd_addr[BD_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 730b966c5eSopenharmony_ci 740b966c5eSopenharmony_ci/****************************************************************************** 750b966c5eSopenharmony_ci** Local type definitions 760b966c5eSopenharmony_ci******************************************************************************/ 770b966c5eSopenharmony_ci 780b966c5eSopenharmony_ci/****************************************************************************** 790b966c5eSopenharmony_ci** Static Variables 800b966c5eSopenharmony_ci******************************************************************************/ 810b966c5eSopenharmony_ci 820b966c5eSopenharmony_cistatic const tUSERIAL_CFG userial_init_cfg = { 830b966c5eSopenharmony_ci (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1), 840b966c5eSopenharmony_ci USERIAL_BAUD_115200 850b966c5eSopenharmony_ci}; 860b966c5eSopenharmony_ci 870b966c5eSopenharmony_ci/****************************************************************************** 880b966c5eSopenharmony_ci** Functions 890b966c5eSopenharmony_ci******************************************************************************/ 900b966c5eSopenharmony_ci 910b966c5eSopenharmony_ci/***************************************************************************** 920b966c5eSopenharmony_ci** 930b966c5eSopenharmony_ci** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS 940b966c5eSopenharmony_ci** 950b966c5eSopenharmony_ci*****************************************************************************/ 960b966c5eSopenharmony_ci/** LPM disable/enable request */ 970b966c5eSopenharmony_citypedef enum { 980b966c5eSopenharmony_ci BT_VND_LPM_DISABLE, 990b966c5eSopenharmony_ci BT_VND_LPM_ENABLE, 1000b966c5eSopenharmony_ci} bt_vendor_lpm_mode_t; 1010b966c5eSopenharmony_ci 1020b966c5eSopenharmony_cistatic int init(const bt_vendor_callbacks_t *p_cb, unsigned char *local_bdaddr) 1030b966c5eSopenharmony_ci{ 1040b966c5eSopenharmony_ci HILOGI("init, bdaddr:%02x%02x:%02x%02x:%02x%02x", local_bdaddr[0], local_bdaddr[1], local_bdaddr[2], 1050b966c5eSopenharmony_ci local_bdaddr[3], local_bdaddr[4], local_bdaddr[5]); 1060b966c5eSopenharmony_ci 1070b966c5eSopenharmony_ci if (p_cb == NULL) { 1080b966c5eSopenharmony_ci HILOGE("init failed with no user callbacks!"); 1090b966c5eSopenharmony_ci return -1; 1100b966c5eSopenharmony_ci } 1110b966c5eSopenharmony_ci 1120b966c5eSopenharmony_ci#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE) 1130b966c5eSopenharmony_ci HILOGW("*****************************************************************"); 1140b966c5eSopenharmony_ci HILOGW("*****************************************************************"); 1150b966c5eSopenharmony_ci HILOGW("** Warning - BT Vendor Lib is loaded in debug tuning mode!"); 1160b966c5eSopenharmony_ci HILOGW("**"); 1170b966c5eSopenharmony_ci HILOGW("** If this is not intentional, rebuild libbt-vendor.so "); 1180b966c5eSopenharmony_ci HILOGW("** with VENDOR_LIB_RUNTIME_TUNING_ENABLED=FALSE and "); 1190b966c5eSopenharmony_ci HILOGW("** check if any run-time tuning parameters needed to be"); 1200b966c5eSopenharmony_ci HILOGW("** carried to the build-time configuration accordingly."); 1210b966c5eSopenharmony_ci HILOGW("*****************************************************************"); 1220b966c5eSopenharmony_ci HILOGW("*****************************************************************"); 1230b966c5eSopenharmony_ci#endif 1240b966c5eSopenharmony_ci 1250b966c5eSopenharmony_ci userial_vendor_init(); 1260b966c5eSopenharmony_ci upio_init(); 1270b966c5eSopenharmony_ci 1280b966c5eSopenharmony_ci vnd_load_conf(VENDOR_LIB_CONF_FILE); 1290b966c5eSopenharmony_ci 1300b966c5eSopenharmony_ci /* store reference to user callbacks */ 1310b966c5eSopenharmony_ci bt_vendor_cbacks = (bt_vendor_callbacks_t *)p_cb; 1320b966c5eSopenharmony_ci 1330b966c5eSopenharmony_ci#if (BRCM_A2DP_OFFLOAD == TRUE) 1340b966c5eSopenharmony_ci brcm_vnd_a2dp_init(bt_vendor_cbacks); 1350b966c5eSopenharmony_ci#endif 1360b966c5eSopenharmony_ci 1370b966c5eSopenharmony_ci /* This is handed over from the stack */ 1380b966c5eSopenharmony_ci return memcpy_s(vnd_local_bd_addr, BD_ADDR_LEN, local_bdaddr, BD_ADDR_LEN); 1390b966c5eSopenharmony_ci} 1400b966c5eSopenharmony_ci 1410b966c5eSopenharmony_ci/** Requested operations */ 1420b966c5eSopenharmony_cistatic int op(bt_opcode_t opcode, void *param) 1430b966c5eSopenharmony_ci{ 1440b966c5eSopenharmony_ci int retval = 0; 1450b966c5eSopenharmony_ci 1460b966c5eSopenharmony_ci switch (opcode) { 1470b966c5eSopenharmony_ci case BT_OP_POWER_ON: // BT_VND_OP_POWER_CTRL 1480b966c5eSopenharmony_ci upio_set_bluetooth_power(UPIO_BT_POWER_OFF); 1490b966c5eSopenharmony_ci upio_set_bluetooth_power(UPIO_BT_POWER_ON); 1500b966c5eSopenharmony_ci break; 1510b966c5eSopenharmony_ci 1520b966c5eSopenharmony_ci case BT_OP_POWER_OFF: // BT_VND_OP_POWER_CTRL 1530b966c5eSopenharmony_ci upio_set_bluetooth_power(UPIO_BT_POWER_OFF); 1540b966c5eSopenharmony_ci hw_lpm_set_wake_state(false); 1550b966c5eSopenharmony_ci break; 1560b966c5eSopenharmony_ci 1570b966c5eSopenharmony_ci case BT_OP_HCI_CHANNEL_OPEN: { // BT_VND_OP_USERIAL_OPEN 1580b966c5eSopenharmony_ci int(*fd_array)[] = (int(*)[])param; 1590b966c5eSopenharmony_ci int fd, idx; 1600b966c5eSopenharmony_ci fd = userial_vendor_open((tUSERIAL_CFG *)&userial_init_cfg); 1610b966c5eSopenharmony_ci if (fd != -1) { 1620b966c5eSopenharmony_ci for (idx = 0; idx < HCI_MAX_CHANNEL; idx++) 1630b966c5eSopenharmony_ci (*fd_array)[idx] = fd; 1640b966c5eSopenharmony_ci 1650b966c5eSopenharmony_ci retval = 1; 1660b966c5eSopenharmony_ci } 1670b966c5eSopenharmony_ci /* retval contains numbers of open fd of HCI channels */ 1680b966c5eSopenharmony_ci break; 1690b966c5eSopenharmony_ci } 1700b966c5eSopenharmony_ci case BT_OP_HCI_CHANNEL_CLOSE: // BT_VND_OP_USERIAL_CLOSE 1710b966c5eSopenharmony_ci userial_vendor_close(); 1720b966c5eSopenharmony_ci break; 1730b966c5eSopenharmony_ci 1740b966c5eSopenharmony_ci case BT_OP_INIT: // BT_VND_OP_FW_CFG 1750b966c5eSopenharmony_ci hw_config_start(); 1760b966c5eSopenharmony_ci break; 1770b966c5eSopenharmony_ci 1780b966c5eSopenharmony_ci case BT_OP_GET_LPM_TIMER: { // BT_VND_OP_GET_LPM_IDLE_TIMEOUT 1790b966c5eSopenharmony_ci uint32_t *timeout_ms = (uint32_t *)param; 1800b966c5eSopenharmony_ci *timeout_ms = hw_lpm_get_idle_timeout(); 1810b966c5eSopenharmony_ci break; 1820b966c5eSopenharmony_ci } 1830b966c5eSopenharmony_ci 1840b966c5eSopenharmony_ci case BT_OP_LPM_ENABLE: 1850b966c5eSopenharmony_ci retval = hw_lpm_enable(BT_VND_LPM_ENABLE); 1860b966c5eSopenharmony_ci break; 1870b966c5eSopenharmony_ci 1880b966c5eSopenharmony_ci case BT_OP_LPM_DISABLE: 1890b966c5eSopenharmony_ci retval = hw_lpm_enable(BT_VND_LPM_DISABLE); 1900b966c5eSopenharmony_ci break; 1910b966c5eSopenharmony_ci 1920b966c5eSopenharmony_ci case BT_OP_WAKEUP_LOCK: 1930b966c5eSopenharmony_ci hw_lpm_set_wake_state(TRUE); 1940b966c5eSopenharmony_ci break; 1950b966c5eSopenharmony_ci case BT_OP_WAKEUP_UNLOCK: 1960b966c5eSopenharmony_ci hw_lpm_set_wake_state(FALSE); 1970b966c5eSopenharmony_ci break; 1980b966c5eSopenharmony_ci case BT_OP_EVENT_CALLBACK: 1990b966c5eSopenharmony_ci hw_process_event((HC_BT_HDR *)param); 2000b966c5eSopenharmony_ci break; 2010b966c5eSopenharmony_ci } 2020b966c5eSopenharmony_ci 2030b966c5eSopenharmony_ci return retval; 2040b966c5eSopenharmony_ci} 2050b966c5eSopenharmony_ci 2060b966c5eSopenharmony_ci/** Closes the interface */ 2070b966c5eSopenharmony_cistatic void cleanup(void) 2080b966c5eSopenharmony_ci{ 2090b966c5eSopenharmony_ci BTVNDDBG("cleanup"); 2100b966c5eSopenharmony_ci upio_cleanup(); 2110b966c5eSopenharmony_ci bt_vendor_cbacks = NULL; 2120b966c5eSopenharmony_ci} 2130b966c5eSopenharmony_ci 2140b966c5eSopenharmony_ci// Entry point of DLib 2150b966c5eSopenharmony_ciconst bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { 2160b966c5eSopenharmony_ci sizeof(bt_vendor_interface_t), 2170b966c5eSopenharmony_ci init, 2180b966c5eSopenharmony_ci op, 2190b966c5eSopenharmony_ci cleanup}; 220