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 
bt_hci_set_transport()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 
bt_hci_init_transport(int * pFd)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 
bt_hci_init_transport_id(int chId)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 
bt_hci_deinit_transport(int * pFd)148 int bt_hci_deinit_transport(int *pFd)
149 {
150     close(pFd[0]);
151     close(pFd[1]);
152     return TRUE;
153 }
154