upload android base code part4
This commit is contained in:
parent
b9e30e05b1
commit
78ea2404cd
23455 changed files with 5250148 additions and 0 deletions
24
android/hardware/marvell/bt/libbt-vendor/Android.mk
Normal file
24
android/hardware/marvell/bt/libbt-vendor/Android.mk
Normal file
|
@ -0,0 +1,24 @@
|
|||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
BDROID_DIR := $(TOP_DIR)system/bt
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
bt_vendor_mrvl.c \
|
||||
hardware_mrvl.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(BDROID_DIR)/hci/include
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcutils \
|
||||
liblog
|
||||
|
||||
LOCAL_MODULE := libbt-vendor
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||
LOCAL_MODULE_OWNER := marvell
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
169
android/hardware/marvell/bt/libbt-vendor/bt_vendor_mrvl.c
Normal file
169
android/hardware/marvell/bt/libbt-vendor/bt_vendor_mrvl.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define LOG_TAG "bt_vendor_mrvl"
|
||||
|
||||
#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 <utils/Log.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 "M002"
|
||||
|
||||
|
||||
/***********************************************************
|
||||
* Externs
|
||||
***********************************************************
|
||||
*/
|
||||
void hw_mrvl_config_start(void);
|
||||
void hw_mrvl_sco_config(void);
|
||||
|
||||
/***********************************************************
|
||||
* Local variables
|
||||
***********************************************************
|
||||
*/
|
||||
static const char mchar_port[] = "/dev/mbtchar0";
|
||||
static int mchar_fd = -1;
|
||||
|
||||
/***********************************************************
|
||||
* Global variables
|
||||
***********************************************************
|
||||
*/
|
||||
bt_vendor_callbacks_t *vnd_cb;
|
||||
unsigned char bdaddr[6];
|
||||
|
||||
/***********************************************************
|
||||
* Local functions
|
||||
***********************************************************
|
||||
*/
|
||||
static int bt_vnd_mrvl_if_init(const bt_vendor_callbacks_t *p_cb,
|
||||
unsigned char *local_bdaddr)
|
||||
{
|
||||
ALOGI("Marvell BT Vendor Lib: ver %s", VERSION);
|
||||
vnd_cb = (bt_vendor_callbacks_t *) p_cb;
|
||||
memcpy(bdaddr, local_bdaddr, sizeof(bdaddr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bt_vnd_mrvl_if_op(bt_vendor_opcode_t opcode, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
int *power_state = NULL;
|
||||
int local_st = 0;
|
||||
|
||||
/* ALOGD("opcode = %d", opcode); */
|
||||
switch (opcode) {
|
||||
case BT_VND_OP_POWER_CTRL:
|
||||
power_state = (int *)param;
|
||||
if (BT_VND_PWR_OFF == *power_state) {
|
||||
ALOGD("Power off");
|
||||
} else if (BT_VND_PWR_ON == *power_state) {
|
||||
ALOGD("Power on");
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
break;
|
||||
case BT_VND_OP_FW_CFG:
|
||||
hw_mrvl_config_start();
|
||||
break;
|
||||
case BT_VND_OP_SCO_CFG:
|
||||
hw_mrvl_sco_config();
|
||||
break;
|
||||
case BT_VND_OP_USERIAL_OPEN:
|
||||
mchar_fd = open(mchar_port, O_RDWR|O_NOCTTY);
|
||||
if (mchar_fd < 0) {
|
||||
ALOGE("Fail to open port %s", mchar_port);
|
||||
ret = -1;
|
||||
} else {
|
||||
ALOGD("open port %s success", mchar_port);
|
||||
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);
|
||||
ALOGD("close port %s", mchar_port);
|
||||
if (close(mchar_fd) < 0) {
|
||||
ALOGE("Fail to close port %s", mchar_port);
|
||||
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;
|
||||
case BT_VND_OP_EPILOG:
|
||||
if (vnd_cb)
|
||||
vnd_cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
} /* switch (opcode) */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static 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,
|
||||
};
|
||||
|
341
android/hardware/marvell/bt/libbt-vendor/hardware_mrvl.c
Normal file
341
android/hardware/marvell/bt/libbt-vendor/hardware_mrvl.c
Normal file
|
@ -0,0 +1,341 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#define LOG_TAG "hardware_mrvl"
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "bt_vendor_lib.h"
|
||||
#include "bt_hci_bdroid.h"
|
||||
|
||||
#define HCI_CMD_MARVELL_WRITE_PCM_SETTINGS 0xFC07
|
||||
#define HCI_CMD_MARVELL_WRITE_PCM_SYNC_SETTINGS 0xFC28
|
||||
#define HCI_CMD_MARVELL_WRITE_PCM_LINK_SETTINGS 0xFC29
|
||||
#define HCI_CMD_MARVELL_SET_SCO_DATA_PATH 0xFC1D
|
||||
#define HCI_CMD_MARVELL_WRITE_BD_ADDRESS 0xFC22
|
||||
|
||||
#define WRITE_PCM_SETTINGS_SIZE 1
|
||||
#define WRITE_PCM_SYNC_SETTINGS_SIZE 3
|
||||
#define WRITE_PCM_LINK_SETTINGS_SIZE 2
|
||||
#define SET_SCO_DATA_PATH_SIZE 1
|
||||
#define WRITE_BD_ADDRESS_SIZE 8
|
||||
|
||||
|
||||
#define HCI_CMD_PREAMBLE_SIZE 3
|
||||
|
||||
#define HCI_EVT_CMD_CMPL_OPCODE 3
|
||||
|
||||
#define STREAM_TO_UINT16(u16, p) \
|
||||
do { \
|
||||
u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \
|
||||
(p) += 2; \
|
||||
} while (0)
|
||||
|
||||
#define UINT16_TO_STREAM(p, u16) \
|
||||
do { \
|
||||
*(p)++ = (uint8_t)(u16); \
|
||||
*(p)++ = (uint8_t)((u16) >> 8); \
|
||||
} while (0)
|
||||
|
||||
struct bt_evt_param_t {
|
||||
uint16_t cmd;
|
||||
uint8_t cmd_ret_param;
|
||||
};
|
||||
|
||||
/***********************************************************
|
||||
* Externs
|
||||
***********************************************************
|
||||
*/
|
||||
extern unsigned char bdaddr[6];
|
||||
extern bt_vendor_callbacks_t *vnd_cb;
|
||||
|
||||
/***********************************************************
|
||||
* Local variables
|
||||
***********************************************************
|
||||
*/
|
||||
static uint8_t write_pcm_settings[WRITE_PCM_SETTINGS_SIZE] = {
|
||||
0x02
|
||||
};
|
||||
|
||||
static uint8_t write_pcm_sync_settings[WRITE_PCM_SYNC_SETTINGS_SIZE] = {
|
||||
0x03,
|
||||
0x00,
|
||||
0x03
|
||||
};
|
||||
|
||||
static uint8_t write_pcm_link_settings[WRITE_PCM_LINK_SETTINGS_SIZE] = {
|
||||
0x03,
|
||||
0x00
|
||||
};
|
||||
|
||||
static uint8_t set_sco_data_path[SET_SCO_DATA_PATH_SIZE] = {
|
||||
0x01
|
||||
};
|
||||
|
||||
static uint8_t write_bd_address[WRITE_BD_ADDRESS_SIZE] = {
|
||||
0xFE, /* Parameter ID */
|
||||
0x06, /* bd_addr length */
|
||||
0x00, /* 6th byte of bd_addr */
|
||||
0x00, /* 5th */
|
||||
0x00, /* 4th */
|
||||
0x00, /* 3rd */
|
||||
0x00, /* 2nd */
|
||||
0x00 /* 1st */
|
||||
};
|
||||
|
||||
/***********************************************************
|
||||
* Local functions
|
||||
***********************************************************
|
||||
*/
|
||||
static char *cmd_to_str(uint16_t cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
case HCI_CMD_MARVELL_WRITE_PCM_SETTINGS:
|
||||
return "write_pcm_settings";
|
||||
case HCI_CMD_MARVELL_WRITE_PCM_SYNC_SETTINGS:
|
||||
return "write_pcm_sync_settings";
|
||||
case HCI_CMD_MARVELL_WRITE_PCM_LINK_SETTINGS:
|
||||
return "write_pcm_link_settings";
|
||||
case HCI_CMD_MARVELL_SET_SCO_DATA_PATH:
|
||||
return "set_sco_data_path";
|
||||
case HCI_CMD_MARVELL_WRITE_BD_ADDRESS:
|
||||
return "write_bd_address";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "unknown command";
|
||||
}
|
||||
|
||||
static void populate_bd_addr_params(uint8_t *params, uint8_t *addr)
|
||||
{
|
||||
assert(params && addr);
|
||||
|
||||
*params++ = addr[5];
|
||||
*params++ = addr[4];
|
||||
*params++ = addr[3];
|
||||
*params++ = addr[2];
|
||||
*params++ = addr[1];
|
||||
*params = addr[0];
|
||||
}
|
||||
|
||||
static HC_BT_HDR *build_cmd_buf(uint16_t cmd, uint8_t pl_len, uint8_t *payload)
|
||||
{
|
||||
HC_BT_HDR *p_buf = NULL;
|
||||
uint16_t cmd_len = HCI_CMD_PREAMBLE_SIZE + pl_len;
|
||||
uint8_t *p;
|
||||
|
||||
assert(vnd_cb && payload);
|
||||
|
||||
p_buf = (HC_BT_HDR *) vnd_cb->alloc(BT_HC_HDR_SIZE + cmd_len);
|
||||
|
||||
if (!p_buf)
|
||||
return NULL;
|
||||
|
||||
p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
|
||||
p_buf->offset = 0;
|
||||
p_buf->layer_specific = 0;
|
||||
p_buf->len = cmd_len;
|
||||
|
||||
p = (uint8_t *) (p_buf + 1);
|
||||
|
||||
/* opcode */
|
||||
UINT16_TO_STREAM(p, cmd);
|
||||
|
||||
/* length of payload */
|
||||
*p = pl_len;
|
||||
++p;
|
||||
|
||||
/* payload */
|
||||
memcpy(p, payload, pl_len);
|
||||
|
||||
return p_buf;
|
||||
}
|
||||
|
||||
static void parse_evt_buf(HC_BT_HDR *p_evt_buf,
|
||||
struct bt_evt_param_t *evt_params)
|
||||
{
|
||||
uint8_t *p = (uint8_t *) (p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
|
||||
|
||||
assert(p_evt_buf && evt_params);
|
||||
|
||||
/* opcode */
|
||||
STREAM_TO_UINT16(evt_params->cmd, p);
|
||||
|
||||
/* command return parameter */
|
||||
evt_params->cmd_ret_param = *p;
|
||||
}
|
||||
|
||||
static void hw_mrvl_config_start_cb(void *p_mem)
|
||||
{
|
||||
HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
|
||||
struct bt_evt_param_t evt_params = {0, 0};
|
||||
|
||||
assert(vnd_cb && p_mem);
|
||||
|
||||
parse_evt_buf(p_evt_buf, &evt_params);
|
||||
|
||||
/* free the buffer */
|
||||
vnd_cb->dealloc(p_evt_buf);
|
||||
|
||||
switch (evt_params.cmd) {
|
||||
case HCI_CMD_MARVELL_WRITE_BD_ADDRESS:
|
||||
/* fw config succeeds */
|
||||
ALOGI("FW config succeeds!");
|
||||
vnd_cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
|
||||
return;
|
||||
|
||||
default:
|
||||
ALOGE("Received event for unexpected cmd (0x%04hX). Fail.",
|
||||
evt_params.cmd);
|
||||
break;
|
||||
} /* end of switch (evt_params.cmd) */
|
||||
|
||||
ALOGE("Vendor lib fwcfg aborted");
|
||||
vnd_cb->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
|
||||
}
|
||||
|
||||
static void hw_mrvl_sco_config_cb(void *p_mem)
|
||||
{
|
||||
HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
|
||||
struct bt_evt_param_t evt_params = {0, 0};
|
||||
uint16_t cmd;
|
||||
HC_BT_HDR *p_buf;
|
||||
|
||||
assert(vnd_cb && p_mem);
|
||||
|
||||
parse_evt_buf(p_evt_buf, &evt_params);
|
||||
|
||||
/* free the buffer */
|
||||
vnd_cb->dealloc(p_evt_buf);
|
||||
|
||||
switch (evt_params.cmd) {
|
||||
case HCI_CMD_MARVELL_WRITE_PCM_SETTINGS:
|
||||
/* Send HCI_CMD_MARVELL_WRITE_PCM_SYNC_SETTINGS */
|
||||
cmd = HCI_CMD_MARVELL_WRITE_PCM_SYNC_SETTINGS;
|
||||
p_buf = build_cmd_buf(cmd,
|
||||
WRITE_PCM_SYNC_SETTINGS_SIZE,
|
||||
write_pcm_sync_settings);
|
||||
break;
|
||||
|
||||
case HCI_CMD_MARVELL_WRITE_PCM_SYNC_SETTINGS:
|
||||
/* Send HCI_CMD_MARVELL_WRITE_PCM_LINK_SETTINGS */
|
||||
cmd = HCI_CMD_MARVELL_WRITE_PCM_LINK_SETTINGS;
|
||||
p_buf = build_cmd_buf(cmd,
|
||||
WRITE_PCM_LINK_SETTINGS_SIZE,
|
||||
write_pcm_link_settings);
|
||||
break;
|
||||
|
||||
case HCI_CMD_MARVELL_WRITE_PCM_LINK_SETTINGS:
|
||||
/* Send HCI_CMD_MARVELL_SET_SCO_DATA_PATH */
|
||||
cmd = HCI_CMD_MARVELL_SET_SCO_DATA_PATH;
|
||||
p_buf = build_cmd_buf(cmd,
|
||||
SET_SCO_DATA_PATH_SIZE,
|
||||
set_sco_data_path);
|
||||
break;
|
||||
|
||||
case HCI_CMD_MARVELL_SET_SCO_DATA_PATH:
|
||||
/* sco config succeeds */
|
||||
ALOGI("SCO PCM config succeeds!");
|
||||
vnd_cb->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
|
||||
return;
|
||||
|
||||
default:
|
||||
ALOGE("Received event for unexpected cmd (0x%04hX). Fail.",
|
||||
evt_params.cmd);
|
||||
p_buf = NULL;
|
||||
break;
|
||||
} /* switch (evt_params.cmd) */
|
||||
|
||||
if (p_buf) {
|
||||
ALOGI("Sending hci command 0x%04hX (%s)", cmd, cmd_to_str(cmd));
|
||||
if (vnd_cb->xmit_cb(cmd, p_buf, hw_mrvl_sco_config_cb))
|
||||
return;
|
||||
else
|
||||
vnd_cb->dealloc(p_buf);
|
||||
}
|
||||
|
||||
ALOGE("Vendor lib scocfg aborted");
|
||||
vnd_cb->scocfg_cb(BT_VND_OP_RESULT_FAIL);
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
* Global functions
|
||||
***********************************************************
|
||||
*/
|
||||
void hw_mrvl_config_start(void)
|
||||
{
|
||||
HC_BT_HDR *p_buf;
|
||||
uint16_t cmd;
|
||||
|
||||
assert(vnd_cb);
|
||||
|
||||
ALOGI("Start HW config ...");
|
||||
/* Start with HCI_CMD_MARVELL_WRITE_BD_ADDRESS */
|
||||
ALOGI("Setting bd addr to %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX",
|
||||
bdaddr[0], bdaddr[1], bdaddr[2],
|
||||
bdaddr[3], bdaddr[4], bdaddr[5]);
|
||||
populate_bd_addr_params(write_bd_address + 2, bdaddr);
|
||||
|
||||
cmd = HCI_CMD_MARVELL_WRITE_BD_ADDRESS;
|
||||
p_buf = build_cmd_buf(cmd,
|
||||
WRITE_BD_ADDRESS_SIZE,
|
||||
write_bd_address);
|
||||
|
||||
if (p_buf) {
|
||||
ALOGI("Sending hci command 0x%04hX (%s)", cmd, cmd_to_str(cmd));
|
||||
if (vnd_cb->xmit_cb(cmd, p_buf, hw_mrvl_config_start_cb))
|
||||
return;
|
||||
else
|
||||
vnd_cb->dealloc(p_buf);
|
||||
}
|
||||
|
||||
ALOGE("Vendor lib fwcfg aborted");
|
||||
vnd_cb->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
|
||||
}
|
||||
|
||||
|
||||
void hw_mrvl_sco_config(void)
|
||||
{
|
||||
HC_BT_HDR *p_buf;
|
||||
uint16_t cmd;
|
||||
|
||||
assert(vnd_cb);
|
||||
|
||||
ALOGI("Start SCO config ...");
|
||||
/* Start with HCI_CMD_MARVELL_WRITE_PCM_SETTINGS */
|
||||
cmd = HCI_CMD_MARVELL_WRITE_PCM_SETTINGS;
|
||||
p_buf = build_cmd_buf(cmd,
|
||||
WRITE_PCM_SETTINGS_SIZE,
|
||||
write_pcm_settings);
|
||||
|
||||
if (p_buf) {
|
||||
ALOGI("Sending hci command 0x%04hX (%s)", cmd, cmd_to_str(cmd));
|
||||
if (vnd_cb->xmit_cb(cmd, p_buf, hw_mrvl_sco_config_cb))
|
||||
return;
|
||||
else
|
||||
vnd_cb->dealloc(p_buf);
|
||||
}
|
||||
|
||||
ALOGE("Vendor lib scocfg aborted");
|
||||
vnd_cb->scocfg_cb(BT_VND_OP_RESULT_FAIL);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue