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