1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Marvell International Ltd.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #define LOG_TAG "bt_vendor_mrvl"
19
20 #include <time.h>
21 #include <errno.h>
22 #include <sched.h>
23 #include <stdio.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <termios.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <signal.h>
31 #include <sys/types.h>
32 #include <sys/select.h>
33 #include <sys/mman.h>
34 #include <pthread.h>
35 #include <utils/Log.h>
36
37 #include "bt_vendor_lib.h"
38
39
40 /* ioctl command to release the read thread before driver close */
41 #define MBTCHAR_IOCTL_RELEASE _IO('M', 1)
42
43 #define VERSION "M002"
44
45
46 /***********************************************************
47 * Externs
48 ***********************************************************
49 */
50 void hw_mrvl_config_start(void);
51 void hw_mrvl_sco_config(void);
52
53 /***********************************************************
54 * Local variables
55 ***********************************************************
56 */
57 static const char mchar_port[] = "/dev/mbtchar0";
58 static int mchar_fd = -1;
59
60 /***********************************************************
61 * Global variables
62 ***********************************************************
63 */
64 bt_vendor_callbacks_t *vnd_cb;
65 unsigned char bdaddr[6];
66
67 /***********************************************************
68 * Local functions
69 ***********************************************************
70 */
bt_vnd_mrvl_if_init(const bt_vendor_callbacks_t * p_cb,unsigned char * local_bdaddr)71 static int bt_vnd_mrvl_if_init(const bt_vendor_callbacks_t *p_cb,
72 unsigned char *local_bdaddr)
73 {
74 ALOGI("Marvell BT Vendor Lib: ver %s", VERSION);
75 vnd_cb = (bt_vendor_callbacks_t *) p_cb;
76 memcpy(bdaddr, local_bdaddr, sizeof(bdaddr));
77 return 0;
78 }
79
bt_vnd_mrvl_if_op(bt_vendor_opcode_t opcode,void * param)80 static int bt_vnd_mrvl_if_op(bt_vendor_opcode_t opcode, void *param)
81 {
82 int ret = 0;
83 int *power_state = NULL;
84 int local_st = 0;
85
86 /* ALOGD("opcode = %d", opcode); */
87 switch (opcode) {
88 case BT_VND_OP_POWER_CTRL:
89 power_state = (int *)param;
90 if (BT_VND_PWR_OFF == *power_state) {
91 ALOGD("Power off");
92 } else if (BT_VND_PWR_ON == *power_state) {
93 ALOGD("Power on");
94 } else {
95 ret = -1;
96 }
97 break;
98 case BT_VND_OP_FW_CFG:
99 hw_mrvl_config_start();
100 break;
101 case BT_VND_OP_SCO_CFG:
102 hw_mrvl_sco_config();
103 break;
104 case BT_VND_OP_USERIAL_OPEN:
105 mchar_fd = open(mchar_port, O_RDWR|O_NOCTTY);
106 if (mchar_fd < 0) {
107 ALOGE("Fail to open port %s", mchar_port);
108 ret = -1;
109 } else {
110 ALOGD("open port %s success", mchar_port);
111 ret = 1;
112 }
113 ((int *)param)[0] = mchar_fd;
114 break;
115 case BT_VND_OP_USERIAL_CLOSE:
116 if (mchar_fd < 0) {
117 ret = -1;
118 } else {
119 /* mbtchar port is blocked on read. Release the port
120 * before we close it.
121 */
122 ioctl(mchar_fd, MBTCHAR_IOCTL_RELEASE, &local_st);
123 /* Give it sometime before we close the mbtchar */
124 usleep(1000);
125 ALOGD("close port %s", mchar_port);
126 if (close(mchar_fd) < 0) {
127 ALOGE("Fail to close port %s", mchar_port);
128 ret = -1;
129 } else {
130 mchar_fd = -1; /* closed successfully */
131 }
132 }
133 break;
134 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
135 break;
136 case BT_VND_OP_LPM_SET_MODE:
137 /* TODO: Enable or disable LPM mode on BT Controller.
138 * ret = xx;
139 */
140 if (vnd_cb)
141 vnd_cb->lpm_cb(ret);
142
143 break;
144 case BT_VND_OP_LPM_WAKE_SET_STATE:
145 break;
146 case BT_VND_OP_EPILOG:
147 if (vnd_cb)
148 vnd_cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
149 break;
150 default:
151 ret = -1;
152 break;
153 } /* switch (opcode) */
154
155 return ret;
156 }
157
bt_vnd_mrvl_if_cleanup(void)158 static void bt_vnd_mrvl_if_cleanup(void)
159 {
160 return;
161 }
162
163 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
164 sizeof(bt_vendor_interface_t),
165 bt_vnd_mrvl_if_init,
166 bt_vnd_mrvl_if_op,
167 bt_vnd_mrvl_if_cleanup,
168 };
169
170