10ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/* 20ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Copyright 2012 The Android Open Source Project 30ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 40ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Licensed under the Apache License, Version 2.0 (the "License"); 50ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * you may not use this file except in compliance with the License. 60ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * You may obtain a copy of the License at 70ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 80ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * http://www.apache.org/licenses/LICENSE-2.0 90ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Unless required by applicable law or agreed to in writing, software 110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * distributed under the License is distributed on an "AS IS" BASIS, 120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * See the License for the specific language governing permissions and 140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * limitations under the License. 150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel */ 160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/****************************************************************************** 180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Filename: hci_smd.c 200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Description: Contains vendor-specific userial functions 220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ******************************************************************************/ 240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define LOG_TAG "bt_vendor" 260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include "bt_vendor_qcom.h" 280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include "hci_smd.h" 29abb4fd870fa1a3dd91a71f6e0d33d6aaa44079c1Jiyong Park 30abb4fd870fa1a3dd91a71f6e0d33d6aaa44079c1Jiyong Park#include <errno.h> 31abb4fd870fa1a3dd91a71f6e0d33d6aaa44079c1Jiyong Park#include <fcntl.h> 32abb4fd870fa1a3dd91a71f6e0d33d6aaa44079c1Jiyong Park#include <stdio.h> 330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <string.h> 34abb4fd870fa1a3dd91a71f6e0d33d6aaa44079c1Jiyong Park#include <termios.h> 35abb4fd870fa1a3dd91a71f6e0d33d6aaa44079c1Jiyong Park#include <unistd.h> 36abb4fd870fa1a3dd91a71f6e0d33d6aaa44079c1Jiyong Park 370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <cutils/properties.h> 38abb4fd870fa1a3dd91a71f6e0d33d6aaa44079c1Jiyong Park#include <utils/Log.h> 390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/***************************************************************************** 410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** Macros & Constants 420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel*****************************************************************************/ 430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define NUM_OF_DEVS 2 440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic char *s_pszDevSmd[] = { 450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel "/dev/smd3", 460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel "/dev/smd2" 470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel}; 480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/****************************************************************************** 500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** Externs 510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel******************************************************************************/ 520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelextern int is_bt_ssr_hci; 530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/***************************************************************************** 560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** Functions 570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel*****************************************************************************/ 580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint bt_hci_init_transport_id (int chId ) 600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel struct termios term; 620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int fd = -1; 630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int retry = 0; 640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char ssrvalue[92]= {'\0'}; 650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ssrvalue[0] = '0'; 670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(chId >= 2 || chId <0) 680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY)); 710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel while ((-1 == fd) && (retry < 7)) { 730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("init_transport: Cannot open %s: %s\n. Retry after 2 seconds", 740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel s_pszDevSmd[chId], strerror(errno)); 750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel usleep(2000000); 760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY)); 770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retry++; 780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (-1 == fd) 810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("init_transport: Cannot open %s: %s\n", 830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel s_pszDevSmd[chId], strerror(errno)); 840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Sleep (0.5sec) added giving time for the smd port to be successfully 880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel opened internally. Currently successful return from open doesn't 890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ensure the smd port is successfully opened. 900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel TODO: Following sleep to be removed once SMD port is successfully 910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel opened immediately on return from the aforementioned open call */ 920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get("bluetooth.isSSR", ssrvalue, ""); 940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(ssrvalue[0] == '1') 960ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /*reset the SSR flag */ 980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(chId == 1) 990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 1000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(property_set("bluetooth.isSSR", "0") < 0) 1010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 1020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("SSR: hci_smd.c:SSR case : error in setting up property new\n "); 1030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else 1050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 1060ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("SSR: hci_smd.c:SSR case : Reset the SSr Flag new\n "); 1070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1080ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("hci_smd.c:IN SSR sleep for 500 msec New \n"); 1100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel usleep(500000); 1110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (tcflush(fd, TCIOFLUSH) < 0) 1140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 1150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("init_uart: Cannot flush %s\n", s_pszDevSmd[chId]); 1160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(fd); 1170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 1180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (tcgetattr(fd, &term) < 0) 1210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 1220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("init_uart: Error while getting attributes\n"); 1230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(fd); 1240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 1250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel cfmakeraw(&term); 1280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* JN: Do I need to make flow control configurable, since 4020 cannot 1300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * disable it? 1310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel */ 1320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel term.c_cflag |= (CRTSCTS | CLOCAL); 1330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (tcsetattr(fd, TCSANOW, &term) < 0) 1350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 1360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("init_uart: Error while getting attributes\n"); 1370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(fd); 1380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 1390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("Done intiailizing UART\n"); 1420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return fd; 1430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 1440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint bt_hci_init_transport(int *pFd) 1460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 1470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int i = 0; 1480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int fd; 1490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel for(i=0; i < NUM_OF_DEVS; i++){ 1500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel fd = bt_hci_init_transport_id(i); 1510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(fd < 0 ){ 1520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 1530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel pFd[i] = fd; 1550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return 0; 1570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 1580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint bt_hci_deinit_transport(int *pFd) 1600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 1610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(pFd[0]); 1620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(pFd[1]); 1630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return TRUE; 1640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 165