1982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/* 2982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * Copyright 2012 The Android Open Source Project 3982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * 4982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * Licensed under the Apache License, Version 2.0 (the "License"); 5982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * you may not use this file except in compliance with the License. 6982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * You may obtain a copy of the License at 7982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * 8982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * http://www.apache.org/licenses/LICENSE-2.0 9982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * 10982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * Unless required by applicable law or agreed to in writing, software 11982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * distributed under the License is distributed on an "AS IS" BASIS, 12982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * See the License for the specific language governing permissions and 14982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * limitations under the License. 15982edd19a092114c479134cb16e0af54730edf1fPrashant Malani */ 16982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 17982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/****************************************************************************** 18982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * 19982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * Filename: hardware.c 20982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * 21982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * Description: Contains controller-specific functions, like 22982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * firmware patch download 23982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * low power mode operations 24982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * 25982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ******************************************************************************/ 26982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 27982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define LOG_TAG "bt_vendor" 28982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 29982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <utils/Log.h> 30982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <sys/types.h> 31982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <sys/stat.h> 32982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <signal.h> 33982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <time.h> 34982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <errno.h> 35982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <fcntl.h> 36982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <dirent.h> 37982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <ctype.h> 38982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <cutils/properties.h> 39982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <stdlib.h> 40982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include "bt_hci_bdroid.h" 41982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include "bt_vendor_qcom.h" 42982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <string.h> 43982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define MAX_CNT_RETRY 100 44982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 45982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint hw_config(int nState) 46982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{ 47982edd19a092114c479134cb16e0af54730edf1fPrashant Malani char *szState[] = {"true", "false"}; 48982edd19a092114c479134cb16e0af54730edf1fPrashant Malani char *szReqSt = NULL; 49982edd19a092114c479134cb16e0af54730edf1fPrashant Malani char szBtSocStatus[PROPERTY_VALUE_MAX] = {'\0', }; 50982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 51982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if(nState == BT_VND_PWR_OFF) 52982edd19a092114c479134cb16e0af54730edf1fPrashant Malani szReqSt = szState[1]; 53982edd19a092114c479134cb16e0af54730edf1fPrashant Malani else 54982edd19a092114c479134cb16e0af54730edf1fPrashant Malani szReqSt = szState[0]; 55982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 56982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if((property_get("bluetooth.status", szBtSocStatus, "") <= 0)) 57982edd19a092114c479134cb16e0af54730edf1fPrashant Malani { 58982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if(nState == BT_VND_PWR_ON ) { 59982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGW("Hw_config: First Time BT on after boot.Starting hciattach daemon BTStatus=%s",szBtSocStatus); 60982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if (property_set("bluetooth.hciattach", szReqSt) < 0) 61982edd19a092114c479134cb16e0af54730edf1fPrashant Malani { 62982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGE("Hw_config: Property Setting fail"); 63982edd19a092114c479134cb16e0af54730edf1fPrashant Malani return -1; 64982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 65982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 66982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } else if( !(strncmp(szBtSocStatus, "on", strlen("on")))) { 67982edd19a092114c479134cb16e0af54730edf1fPrashant Malani //BTSOC is already on 68982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGW("Hw_config: nState = %d", nState); 69982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } else { 70982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGW("Hw_config: trigerring hciattach"); 71982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if (property_set("bluetooth.hciattach", szReqSt) < 0) 72982edd19a092114c479134cb16e0af54730edf1fPrashant Malani { 73982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGE("Hw_config: Property Setting fail"); 74982edd19a092114c479134cb16e0af54730edf1fPrashant Malani return -1; 75982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 76982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 77982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 78982edd19a092114c479134cb16e0af54730edf1fPrashant Malani return 0; 79982edd19a092114c479134cb16e0af54730edf1fPrashant Malani} 80982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 81982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint readTrpState() 82982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{ 83982edd19a092114c479134cb16e0af54730edf1fPrashant Malani char szBtStatus[PROPERTY_VALUE_MAX] = {0, }; 84982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if(property_get("bluetooth.status", szBtStatus, "") < 0){ 85982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGE("Fail to get bluetooth status"); 86982edd19a092114c479134cb16e0af54730edf1fPrashant Malani return FALSE; 87982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 88982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 89982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if(!strncmp(szBtStatus, "on", strlen("on"))){ 90982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGI("bluetooth status is on"); 91982edd19a092114c479134cb16e0af54730edf1fPrashant Malani return TRUE; 92982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 93982edd19a092114c479134cb16e0af54730edf1fPrashant Malani return FALSE; 94982edd19a092114c479134cb16e0af54730edf1fPrashant Malani} 95982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 96982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint is_hw_ready() 97982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{ 98982edd19a092114c479134cb16e0af54730edf1fPrashant Malani int i=0; 99982edd19a092114c479134cb16e0af54730edf1fPrashant Malani char szStatus[10] = {0,}; 100982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 101982edd19a092114c479134cb16e0af54730edf1fPrashant Malani for(i=MAX_CNT_RETRY; i>0; i--){ 102982edd19a092114c479134cb16e0af54730edf1fPrashant Malani //TODO :: checking routine 103982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if(readTrpState()==TRUE){ 104982edd19a092114c479134cb16e0af54730edf1fPrashant Malani break; 105982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 106982edd19a092114c479134cb16e0af54730edf1fPrashant Malani usleep(50*1000); 107982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 108982edd19a092114c479134cb16e0af54730edf1fPrashant Malani return (i==0)? FALSE:TRUE; 109982edd19a092114c479134cb16e0af54730edf1fPrashant Malani} 110982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 111982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#if (HW_NEED_END_WITH_HCI_RESET == TRUE) 112982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/******************************************************************************* 113982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** 114982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** Function hw_epilog_cback 115982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** 116982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** Description Callback function for Command Complete Events from HCI 117982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** commands sent in epilog process. 118982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** 119982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** Returns None 120982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** 121982edd19a092114c479134cb16e0af54730edf1fPrashant Malani*******************************************************************************/ 122982edd19a092114c479134cb16e0af54730edf1fPrashant Malanivoid hw_epilog_cback(void *p_mem) 123982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{ 124982edd19a092114c479134cb16e0af54730edf1fPrashant Malani HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; 125982edd19a092114c479134cb16e0af54730edf1fPrashant Malani char *p_name, *p_tmp; 126982edd19a092114c479134cb16e0af54730edf1fPrashant Malani uint8_t *p, status; 127982edd19a092114c479134cb16e0af54730edf1fPrashant Malani uint16_t opcode; 128982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 129982edd19a092114c479134cb16e0af54730edf1fPrashant Malani status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE); 130982edd19a092114c479134cb16e0af54730edf1fPrashant Malani p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; 131982edd19a092114c479134cb16e0af54730edf1fPrashant Malani STREAM_TO_UINT16(opcode,p); 132982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 133982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGI("%s Opcode:0x%04X Status: %d", __FUNCTION__, opcode, status); 134982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 135982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if (bt_vendor_cbacks) 136982edd19a092114c479134cb16e0af54730edf1fPrashant Malani { 137982edd19a092114c479134cb16e0af54730edf1fPrashant Malani /* Must free the RX event buffer */ 138982edd19a092114c479134cb16e0af54730edf1fPrashant Malani bt_vendor_cbacks->dealloc(p_evt_buf); 139982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 140982edd19a092114c479134cb16e0af54730edf1fPrashant Malani /* Once epilog process is done, must call callback to notify caller */ 141982edd19a092114c479134cb16e0af54730edf1fPrashant Malani bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 142982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 143982edd19a092114c479134cb16e0af54730edf1fPrashant Malani} 144982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 145982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/******************************************************************************* 146982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** 147982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** Function hw_epilog_process 148982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** 149982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** Description Sample implementation of epilog process 150982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** 151982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** Returns None 152982edd19a092114c479134cb16e0af54730edf1fPrashant Malani** 153982edd19a092114c479134cb16e0af54730edf1fPrashant Malani*******************************************************************************/ 154982edd19a092114c479134cb16e0af54730edf1fPrashant Malanivoid hw_epilog_process(void) 155982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{ 156982edd19a092114c479134cb16e0af54730edf1fPrashant Malani HC_BT_HDR *p_buf = NULL; 157982edd19a092114c479134cb16e0af54730edf1fPrashant Malani uint8_t *p; 158982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 159982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGI("hw_epilog_process"); 160982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 161982edd19a092114c479134cb16e0af54730edf1fPrashant Malani /* Sending a HCI_RESET */ 162982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if (bt_vendor_cbacks) 163982edd19a092114c479134cb16e0af54730edf1fPrashant Malani { 164982edd19a092114c479134cb16e0af54730edf1fPrashant Malani /* Must allocate command buffer via HC's alloc API */ 165982edd19a092114c479134cb16e0af54730edf1fPrashant Malani p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ 166982edd19a092114c479134cb16e0af54730edf1fPrashant Malani HCI_CMD_PREAMBLE_SIZE); 167982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 168982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 169982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if (p_buf) 170982edd19a092114c479134cb16e0af54730edf1fPrashant Malani { 171982edd19a092114c479134cb16e0af54730edf1fPrashant Malani p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 172982edd19a092114c479134cb16e0af54730edf1fPrashant Malani p_buf->offset = 0; 173982edd19a092114c479134cb16e0af54730edf1fPrashant Malani p_buf->layer_specific = 0; 174982edd19a092114c479134cb16e0af54730edf1fPrashant Malani p_buf->len = HCI_CMD_PREAMBLE_SIZE; 175982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 176982edd19a092114c479134cb16e0af54730edf1fPrashant Malani p = (uint8_t *) (p_buf + 1); 177982edd19a092114c479134cb16e0af54730edf1fPrashant Malani UINT16_TO_STREAM(p, HCI_RESET); 178982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *p = 0; /* parameter length */ 179982edd19a092114c479134cb16e0af54730edf1fPrashant Malani 180982edd19a092114c479134cb16e0af54730edf1fPrashant Malani /* Send command via HC's xmit_cb API */ 181982edd19a092114c479134cb16e0af54730edf1fPrashant Malani bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_epilog_cback); 182982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 183982edd19a092114c479134cb16e0af54730edf1fPrashant Malani else 184982edd19a092114c479134cb16e0af54730edf1fPrashant Malani { 185982edd19a092114c479134cb16e0af54730edf1fPrashant Malani if (bt_vendor_cbacks) 186982edd19a092114c479134cb16e0af54730edf1fPrashant Malani { 187982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ALOGE("vendor lib epilog process aborted [no buffer]"); 188982edd19a092114c479134cb16e0af54730edf1fPrashant Malani bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_FAIL); 189982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 190982edd19a092114c479134cb16e0af54730edf1fPrashant Malani } 191982edd19a092114c479134cb16e0af54730edf1fPrashant Malani} 192982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#endif // (HW_NEED_END_WITH_HCI_RESET == TRUE) 193