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:      userial_vendor.c
     20  *
     21  *  Description:   Contains vendor-specific userial functions
     22  *
     23  ******************************************************************************/
     24 
     25 #define LOG_TAG "bt_userial_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 "userial_vendor.h"
     34 
     35 bt_hci_transport_device_type bt_hci_set_transport()
     36 {
     37     int ret;
     38     char transport_type[10] = {0,};
     39     bt_hci_transport_device_type bt_hci_transport_device;
     40 
     41     ret = property_get("ro.qualcomm.bt.hci_transport", transport_type, NULL);
     42     if(ret == 0)
     43         printf("ro.qualcomm.bt.hci_transport not set\n");
     44     else
     45         printf("ro.qualcomm.bt.hci_transport: %s \n", transport_type);
     46 
     47     if (!strcasecmp(transport_type, "smd"))
     48     {
     49         bt_hci_transport_device.type = BT_HCI_SMD;
     50         bt_hci_transport_device.name = APPS_RIVA_BT_CMD_CH;
     51         bt_hci_transport_device.pkt_ind = 1;
     52     }
     53     else{
     54         bt_hci_transport_device.type = BT_HCI_UART;
     55         bt_hci_transport_device.name = BT_HS_UART_DEVICE;
     56         bt_hci_transport_device.pkt_ind = 0;
     57     }
     58 
     59     return bt_hci_transport_device;
     60 }
     61 
     62 #define NUM_OF_DEVS 2
     63 static char *s_pszDevSmd[] = {
     64     "/dev/smd3",
     65     "/dev/smd2"
     66 };
     67 
     68 int bt_hci_init_transport(int *pFd)
     69 {
     70     int i = 0;
     71     int fd;
     72     for(i=0; i < NUM_OF_DEVS; i++){
     73        fd = bt_hci_init_transport_id(i);
     74        if(fd < 0 ){
     75           return -1;
     76        }
     77        pFd[i] = fd;
     78     }
     79     return 0;
     80 }
     81 
     82 int bt_hci_init_transport_id (int chId )
     83 {
     84   struct termios   term;
     85   int fd = -1;
     86   int retry = 0;
     87 
     88   if(chId > 2 || chId <0)
     89      return -1;
     90 
     91   fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY));
     92 
     93   while ((-1 == fd) && (retry < 7)) {
     94     ALOGE("init_transport: Cannot open %s: %s\n. Retry after 2 seconds",
     95         bt_hci_transport_device.name, strerror(errno));
     96     usleep(2000000);
     97     fd = open(bt_hci_transport_device.name, (O_RDWR | O_NOCTTY));
     98     retry++;
     99   }
    100 
    101   if (-1 == fd)
    102   {
    103     ALOGE("init_transport: Cannot open %s: %s\n",
    104         bt_hci_transport_device.name, strerror(errno));
    105     return -1;
    106   }
    107 
    108   /* Sleep (0.5sec) added giving time for the smd port to be successfully
    109      opened internally. Currently successful return from open doesn't
    110      ensure the smd port is successfully opened.
    111      TODO: Following sleep to be removed once SMD port is successfully
    112      opened immediately on return from the aforementioned open call */
    113   if(BT_HCI_SMD == bt_hci_transport_device.type)
    114      usleep(500000);
    115 
    116   if (tcflush(fd, TCIOFLUSH) < 0)
    117   {
    118     ALOGE("init_uart: Cannot flush %s\n", bt_hci_transport_device.name);
    119     close(fd);
    120     return -1;
    121   }
    122 
    123   if (tcgetattr(fd, &term) < 0)
    124   {
    125     ALOGE("init_uart: Error while getting attributes\n");
    126     close(fd);
    127     return -1;
    128   }
    129 
    130   cfmakeraw(&term);
    131 
    132   /* JN: Do I need to make flow control configurable, since 4020 cannot
    133    * disable it?
    134    */
    135   term.c_cflag |= (CRTSCTS | CLOCAL);
    136 
    137   if (tcsetattr(fd, TCSANOW, &term) < 0)
    138   {
    139     ALOGE("init_uart: Error while getting attributes\n");
    140     close(fd);
    141     return -1;
    142   }
    143 
    144   ALOGI("Done intiailizing UART\n");
    145   return fd;
    146 }
    147 
    148 int bt_hci_deinit_transport(int *pFd)
    149 {
    150     close(pFd[0]);
    151     close(pFd[1]);
    152     return TRUE;
    153 }
    154