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