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