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
41static char *s_pszDevSmd[] = {
42    "/dev/smd3",
43    "/dev/smd2"
44};
45
46/******************************************************************************
47**  Externs
48******************************************************************************/
49extern int is_bt_ssr_hci;
50
51
52/*****************************************************************************
53**   Functions
54*****************************************************************************/
55
56int 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
142int 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
156int bt_hci_deinit_transport(int *pFd)
157{
158    close(pFd[0]);
159    close(pFd[1]);
160    return TRUE;
161}
162