Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /******************************************************************************
     18  *
     19  *  Filename:      hci_smd.c
     20  *
     21  *  Description:   Contains vendor-specific userial functions
     22  *
     23  ******************************************************************************/
     24 
     25 #define LOG_TAG "bt_vendor"
     26 
     27 #include <utils/Log.h>
     28 #include <termios.h>
     29 #include <fcntl.h>
     30 #include <errno.h>
     31 #include <stdio.h>
     32 #include <string.h>
     33 #include <cutils/properties.h>
     34 #include "bt_vendor_qcom.h"
     35 #include "hci_smd.h"
     36 #include <string.h>
     37 #include <cutils/properties.h>
     38 
     39 /*****************************************************************************
     40 **   Macros & Constants
     41 *****************************************************************************/
     42 #define NUM_OF_DEVS 2
     43 static char *s_pszDevSmd[] = {
     44     "/dev/smd3",
     45     "/dev/smd2"
     46 };
     47 
     48 /******************************************************************************
     49 **  Externs
     50 ******************************************************************************/
     51 extern int is_bt_ssr_hci;
     52 
     53 
     54 /*****************************************************************************
     55 **   Functions
     56 *****************************************************************************/
     57 
     58 int bt_hci_init_transport_id (int chId )
     59 {
     60   struct termios   term;
     61   int fd = -1;
     62   int retry = 0;
     63   char ssrvalue[92]= {'\0'};
     64 
     65   ssrvalue[0] = '0';
     66   if(chId >= 2 || chId <0)
     67      return -1;
     68 
     69   fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY));
     70 
     71   while ((-1 == fd) && (retry < 7)) {
     72     ALOGE("init_transport: Cannot open %s: %s\n. Retry after 2 seconds",
     73         s_pszDevSmd[chId], strerror(errno));
     74     usleep(2000000);
     75     fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY));
     76     retry++;
     77   }
     78 
     79   if (-1 == fd)
     80   {
     81     ALOGE("init_transport: Cannot open %s: %s\n",
     82         s_pszDevSmd[chId], strerror(errno));
     83     return -1;
     84   }
     85 
     86   /* Sleep (0.5sec) added giving time for the smd port to be successfully
     87      opened internally. Currently successful return from open doesn't
     88      ensure the smd port is successfully opened.
     89      TODO: Following sleep to be removed once SMD port is successfully
     90      opened immediately on return from the aforementioned open call */
     91 
     92   property_get("bluetooth.isSSR", ssrvalue, "");
     93 
     94   if(ssrvalue[0] == '1')
     95   {
     96       /*reset the SSR flag */
     97       if(chId == 1)
     98       {
     99           if(property_set("bluetooth.isSSR", "0") < 0)
    100           {
    101               ALOGE("SSR: hci_smd.c:SSR case : error in setting up property new\n ");
    102           }
    103           else
    104           {
    105               ALOGE("SSR: hci_smd.c:SSR case : Reset the SSr Flag new\n ");
    106           }
    107       }
    108       ALOGE("hci_smd.c:IN SSR sleep for 500 msec New \n");
    109       usleep(500000);
    110   }
    111 
    112   if (tcflush(fd, TCIOFLUSH) < 0)
    113   {
    114     ALOGE("init_uart: Cannot flush %s\n", s_pszDevSmd[chId]);
    115     close(fd);
    116     return -1;
    117   }
    118 
    119   if (tcgetattr(fd, &term) < 0)
    120   {
    121     ALOGE("init_uart: Error while getting attributes\n");
    122     close(fd);
    123     return -1;
    124   }
    125 
    126   cfmakeraw(&term);
    127 
    128   /* JN: Do I need to make flow control configurable, since 4020 cannot
    129    * disable it?
    130    */
    131   term.c_cflag |= (CRTSCTS | CLOCAL);
    132 
    133   if (tcsetattr(fd, TCSANOW, &term) < 0)
    134   {
    135     ALOGE("init_uart: Error while getting attributes\n");
    136     close(fd);
    137     return -1;
    138   }
    139 
    140   ALOGI("Done intiailizing UART\n");
    141   return fd;
    142 }
    143 
    144 int bt_hci_init_transport(int *pFd)
    145 {
    146     int i = 0;
    147     int fd;
    148     for(i=0; i < NUM_OF_DEVS; i++){
    149        fd = bt_hci_init_transport_id(i);
    150        if(fd < 0 ){
    151           return -1;
    152        }
    153        pFd[i] = fd;
    154     }
    155     return 0;
    156 }
    157 
    158 int bt_hci_deinit_transport(int *pFd)
    159 {
    160     close(pFd[0]);
    161     close(pFd[1]);
    162     return TRUE;
    163 }
    164