Home | History | Annotate | Download | only in libbt-vendor
      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