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 
     37 /*****************************************************************************
     38 **   Macros & Constants
     39 *****************************************************************************/
     40 #define NUM_OF_DEVS 2
     41 static char *s_pszDevSmd[] = {
     42     "/dev/smd3",
     43     "/dev/smd2"
     44 };
     45 
     46 /******************************************************************************
     47 **  Externs
     48 ******************************************************************************/
     49 extern int is_bt_ssr_hci;
     50 
     51 
     52 /*****************************************************************************
     53 **   Functions
     54 *****************************************************************************/
     55 int bt_hci_init_transport_id (int chId )
     56 {
     57   struct termios   term;
     58   int fd = -1;
     59   int retry = 0;
     60   char ssrvalue[92]= {'\0'};
     61 
     62   ssrvalue[0] = '0';
     63   if(chId >= 2 || chId <0)
     64      return -1;
     65 
     66   fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY));
     67 
     68   while ((-1 == fd) && (retry < 7)) {
     69     ALOGE("init_transport: Cannot open %s: %s\n. Retry after 2 seconds",
     70         s_pszDevSmd[chId], strerror(errno));
     71     usleep(2000000);
     72     fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY));
     73     retry++;
     74   }
     75 
     76   if (-1 == fd)
     77   {
     78     ALOGE("init_transport: Cannot open %s: %s\n",
     79         s_pszDevSmd[chId], strerror(errno));
     80     return -1;
     81   }
     82 
     83   /* Sleep (0.5sec) added giving time for the smd port to be successfully
     84      opened internally. Currently successful return from open doesn't
     85      ensure the smd port is successfully opened.
     86      TODO: Following sleep to be removed once SMD port is successfully
     87      opened immediately on return from the aforementioned open call */
     88 
     89   property_get("bluetooth.isSSR", ssrvalue, "");
     90 
     91   if(ssrvalue[0] == '1')
     92   {
     93       /*reset the SSR flag */
     94       if(chId == 1)
     95       {
     96           if(property_set("bluetooth.isSSR", "0") < 0)
     97           {
     98               ALOGE("SSR: hci_smd.c:SSR case : error in setting up property new\n ");
     99           }
    100           else
    101           {
    102               ALOGE("SSR: hci_smd.c:SSR case : Reset the SSr Flag new\n ");
    103           }
    104       }
    105       ALOGE("hci_smd.c:IN SSR sleep for 500 msec New \n");
    106       usleep(500000);
    107   }
    108 
    109   if (tcflush(fd, TCIOFLUSH) < 0)
    110   {
    111     ALOGE("init_uart: Cannot flush %s\n", s_pszDevSmd[chId]);
    112     close(fd);
    113     return -1;
    114   }
    115 
    116   if (tcgetattr(fd, &term) < 0)
    117   {
    118     ALOGE("init_uart: Error while getting attributes\n");
    119     close(fd);
    120     return -1;
    121   }
    122 
    123   cfmakeraw(&term);
    124 
    125   /* JN: Do I need to make flow control configurable, since 4020 cannot
    126    * disable it?
    127    */
    128   term.c_cflag |= (CRTSCTS | CLOCAL);
    129 
    130   if (tcsetattr(fd, TCSANOW, &term) < 0)
    131   {
    132     ALOGE("init_uart: Error while getting attributes\n");
    133     close(fd);
    134     return -1;
    135   }
    136 
    137   ALOGI("Done intiailizing UART\n");
    138   return fd;
    139 }
    140 
    141 int bt_hci_init_transport(int *pFd)
    142 {
    143     int i = 0;
    144     int fd;
    145     for(i=0; i < NUM_OF_DEVS; i++){
    146        fd = bt_hci_init_transport_id(i);
    147        if(fd < 0 ){
    148           return -1;
    149        }
    150        pFd[i] = fd;
    151     }
    152     return 0;
    153 }
    154 
    155 int bt_hci_deinit_transport(int *pFd)
    156 {
    157     close(pFd[0]);
    158     close(pFd[1]);
    159     return TRUE;
    160 }
    161