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 */ 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 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 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