blob: 93664ccbffebef7b56a676e28f66afe7eb14d26f [file] [log] [blame]
/******************************************************************************
*
* Copyright (C) 2012 Marvell International Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#include <time.h>
#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/mman.h>
#include <pthread.h>
#include "bt_vendor_lib.h"
/* ioctl command to release the read thread before driver close */
#define MBTCHAR_IOCTL_RELEASE _IO ('M',1)
#define VERSION "M001"
static bt_vendor_callbacks_t *vnd_cb = NULL;
static unsigned char bdaddr[6];
static char mchar_port[] = "/dev/mbtchar0";
static int mchar_fd = -1;
int bt_vnd_mrvl_if_init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
{
vnd_cb = p_cb;
memcpy(bdaddr, local_bdaddr, sizeof(bdaddr));
return 0;
}
int bt_vnd_mrvl_if_op(bt_vendor_opcode_t opcode, void *param)
{
int ret = 0;
int power_state;
int local_st = 0;
switch (opcode) {
case BT_VND_OP_POWER_CTRL:
power_state = (int *)param;
if (BT_VND_PWR_OFF == power_state) {
} else if (BT_VND_PWR_ON == power_state) {
} else {
ret = -1;
}
break;
case BT_VND_OP_FW_CFG:
// TODO: Perform any vendor specific initialization or configuration on the BT Controller
// ret = xxx
if (vnd_cb) {
vnd_cb->fwcfg_cb(ret);
}
break;
case BT_VND_OP_SCO_CFG:
// TODO: Perform any vendor specific SCO/PCM configuration on the BT Controller.
// ret = xxx
if (vnd_cb) {
vnd_cb->scocfg_cb(ret);
}
break;
case BT_VND_OP_USERIAL_OPEN:
mchar_fd = open(mchar_port, O_RDWR|O_NOCTTY);
if (mchar_fd < 0) {
ret = -1;
} else {
ret = 1;
}
((int *)param)[0] = mchar_fd;
break;
case BT_VND_OP_USERIAL_CLOSE:
if (mchar_fd < 0) {
ret = -1;
} else {
/* mbtchar port is blocked on read. Release the port before we close it */
ioctl(mchar_fd,MBTCHAR_IOCTL_RELEASE,&local_st);
/* Give it sometime before we close the mbtchar */
usleep(1000);
if (close(mchar_fd) < 0) {
ret = -1;
} else {
mchar_fd = -1; /* closed successfully */
}
}
break;
case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
break;
case BT_VND_OP_LPM_SET_MODE:
// TODO: Enable or disable LPM mode on BT Controller.
// ret = xx;
if (vnd_cb) {
vnd_cb->lpm_cb(ret);
}
break;
case BT_VND_OP_LPM_WAKE_SET_STATE:
break;
default:
ret = -1;
break;
}
return ret;
}
void bt_vnd_mrvl_if_cleanup(void)
{
return;
}
const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
sizeof(bt_vendor_interface_t),
bt_vnd_mrvl_if_init,
bt_vnd_mrvl_if_op,
bt_vnd_mrvl_if_cleanup,
};