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