Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/next/external/cache/sources/hcitools/hciattach_sprd_2.c
Views: 3959
#include <stdio.h>1#include <stdlib.h>2#include <unistd.h>3#include <errno.h>4#include <fcntl.h>5#include <string.h>6#include <signal.h>7#include <time.h>8#include <stdint.h>9#include <sys/termios.h>10#include <sys/ioctl.h>11#include <limits.h>12#include "hciattach.h"1314/******************************************************************************15** Constants & Macros16******************************************************************************/17#define LOG_STR "SPRD Bluetooth"18#define DBG_ON 11920#define SPRD_DBG(fmt, arg...) \21do { \22if (DBG_ON) \23fprintf(stderr, "%s: " fmt "\n" , LOG_STR, ##arg); \24} while(0)2526#define SPRD_ERR(fmt, arg...) \27do { \28fprintf(stderr, "%s ERROR: " fmt "\n", LOG_STR, ##arg);\29perror(LOG_STR" ERROR reason"); \30} while(0)3132#define SPRD_DUMP(buffer, len) \33fprintf(stderr, "%s: ", LOG_STR); \34do { \35int i = 0; \36for (i = 0; i < len; i++) { \37if (i && !(i % 16)) { \38fprintf(stderr, "\n"); \39fprintf(stderr, "%s: ", LOG_STR); \40} \41fprintf(stderr, "%02x ", buffer[i]); \42} \43fprintf(stderr, "\n"); \44} while (0)4546#define CONF_ITEM_TABLE(ITEM, ACTION, BUF, LEN) \47{ #ITEM, ACTION, &(BUF.ITEM), LEN, (sizeof(BUF.ITEM) / LEN) }4849#define UINT8_TO_STREAM(p, u8) \50{ *(p)++ = (uint8_t)(u8); }5152#define STREAM_TO_UINT8(u8, p) \53{ \54(u8) = (uint8_t)(*(p)); \55(p) += 1; \56}5758#define UINT16_TO_STREAM(p, u16) \59{ \60*(p)++ = (uint8_t)(u16); \61*(p)++ = (uint8_t)((u16) >> 8); \62}6364#define STREAM_TO_UINT16(u16, p) \65{ \66(u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \67(p) += 2; \68}6970#define UINT32_TO_STREAM(p, u32) \71{ \72*(p)++ = (uint8_t)(u32); \73*(p)++ = (uint8_t)((u32) >> 8); \74*(p)++ = (uint8_t)((u32) >> 16); \75*(p)++ = (uint8_t)((u32) >> 24); \76}7778#define CONF_COMMENT '#'79#define CONF_DELIMITERS " =\n\r\t"80#define CONF_VALUES_DELIMITERS "=\n\r\t#"81#define CONF_VALUES_PARTITION " ,=\n\r\t#"82#define CONF_MAX_LINE_LEN 2558384#define HCI_PSKEY 0xFCA085#define HCI_VSC_ENABLE_COMMMAND 0xFCA186#define HCI_RF_PARA 0xFCA28788#define RESPONSE_LENGTH 10089#define HCI_CMD_MAX_LEN 25890#define HCI_EVT_CMD_CMPL_OPCODE 391#define HCI_PACKET_TYPE_COMMAND 192#define HCI_CMD_PREAMBLE_SIZE 39394#define FW_NODE_BYTE 695#define FW_DATE_D_BYTE 896#define FW_DATE_M_BYTE 997#define FW_DATE_Y_BYTE 109899#define BT_CONFIG_PATH "/lib/firmware"100#define BT_HC_HDR_SIZE (sizeof(HC_BT_HDR))101#define BT_VND_OP_RESULT_SUCCESS 0102#define BT_VND_OP_RESULT_FAIL 1103#define MSG_STACK_TO_HC_HCI_CMD 0x2000104#define START_STOP_CMD_SIZE 3105#define DUAL_MODE 0106#define DISABLE_BT 0107#define ENABLE_BT 1108109typedef void (*hci_cback)(void *);110typedef int (conf_action_t)(char *p_conf_name, char *p_conf_value, void *buf, int len, int size);111112typedef struct {113uint16_t event;114uint16_t len;115uint16_t offset;116uint16_t layer_specific;117uint8_t data[];118} HC_BT_HDR;119120typedef struct {121uint32_t device_class;122uint8_t feature_set[16];123uint8_t device_addr[6];124uint16_t comp_id;125uint8_t g_sys_uart0_communication_supported;126uint8_t cp2_log_mode;127uint8_t LogLevel;128uint8_t g_central_or_perpheral;129uint16_t Log_BitMask;130uint8_t super_ssp_enable;131uint8_t common_rfu_b3;132uint32_t common_rfu_w[2];133uint32_t le_rfu_w[2];134uint32_t lmp_rfu_w[2];135uint32_t lc_rfu_w[2];136uint16_t g_wbs_nv_117;137uint16_t g_wbs_nv_118;138uint16_t g_nbv_nv_117;139uint16_t g_nbv_nv_118;140uint8_t g_sys_sco_transmit_mode;141uint8_t audio_rfu_b1;142uint8_t audio_rfu_b2;143uint8_t audio_rfu_b3;144uint32_t audio_rfu_w[2];145uint8_t g_sys_sleep_in_standby_supported;146uint8_t g_sys_sleep_master_supported;147uint8_t g_sys_sleep_slave_supported;148uint8_t power_rfu_b1;149uint32_t power_rfu_w[2];150uint32_t win_ext;151uint8_t edr_tx_edr_delay;152uint8_t edr_rx_edr_delay;153uint8_t tx_delay;154uint8_t rx_delay;155uint32_t bb_rfu_w[2];156uint8_t agc_mode;157uint8_t diff_or_eq;158uint8_t ramp_mode;159uint8_t modem_rfu_b1;160uint32_t modem_rfu_w[2];161uint32_t BQB_BitMask_1;162uint32_t BQB_BitMask_2;163uint16_t bt_coex_threshold[8];164uint32_t other_rfu_w[6];165} pskey_config_t;166167typedef struct {168uint16_t g_GainValue_A[6];169uint16_t g_ClassicPowerValue_A[10];170uint16_t g_LEPowerValue_A[16];171uint16_t g_BRChannelpwrvalue_A[8];172uint16_t g_EDRChannelpwrvalue_A[8];173uint16_t g_LEChannelpwrvalue_A[8];174uint16_t g_GainValue_B[6];175uint16_t g_ClassicPowerValue_B[10];176uint16_t g_LEPowerValue_B[16];177uint16_t g_BRChannelpwrvalue_B[8];178uint16_t g_EDRChannelpwrvalue_B[8];179uint16_t g_LEChannelpwrvalue_B[8];180uint16_t LE_fix_powerword;181uint8_t Classic_pc_by_channel;182uint8_t LE_pc_by_channel;183uint8_t RF_switch_mode;184uint8_t Data_Capture_Mode;185uint8_t Analog_IQ_Debug_Mode;186uint8_t RF_common_rfu_b3;187uint32_t RF_common_rfu_w[5];188} rf_config_t;189190typedef struct {191const char *conf_entry;192conf_action_t *p_action;193void *buf;194int len;195int size;196} conf_entry_t;197198static uint8_t local_bdaddr[6]={0x10, 0x11, 0x12, 0x13, 0x14, 0x15};199static pskey_config_t marlin3_pskey;200static rf_config_t marlin3_rf_config;201static int s_bt_fd = -1;202203static const conf_entry_t marlin3_pksey_table[] = {204CONF_ITEM_TABLE(device_class, 0, marlin3_pskey, 1),205CONF_ITEM_TABLE(feature_set, 0, marlin3_pskey, 16),206CONF_ITEM_TABLE(device_addr, 0, marlin3_pskey, 6),207CONF_ITEM_TABLE(comp_id, 0, marlin3_pskey, 1),208CONF_ITEM_TABLE(g_sys_uart0_communication_supported, 0, marlin3_pskey, 1),209CONF_ITEM_TABLE(cp2_log_mode, 0, marlin3_pskey, 1),210CONF_ITEM_TABLE(LogLevel, 0, marlin3_pskey, 1),211CONF_ITEM_TABLE(g_central_or_perpheral, 0, marlin3_pskey, 1),212CONF_ITEM_TABLE(Log_BitMask, 0, marlin3_pskey, 1),213CONF_ITEM_TABLE(super_ssp_enable, 0, marlin3_pskey, 1),214CONF_ITEM_TABLE(common_rfu_b3, 0, marlin3_pskey, 1),215CONF_ITEM_TABLE(common_rfu_w, 0, marlin3_pskey, 2),216CONF_ITEM_TABLE(le_rfu_w, 0, marlin3_pskey, 2),217CONF_ITEM_TABLE(lmp_rfu_w, 0, marlin3_pskey, 2),218CONF_ITEM_TABLE(lc_rfu_w, 0, marlin3_pskey, 2),219CONF_ITEM_TABLE(g_wbs_nv_117, 0, marlin3_pskey, 1),220CONF_ITEM_TABLE(g_wbs_nv_118, 0, marlin3_pskey, 1),221CONF_ITEM_TABLE(g_nbv_nv_117, 0, marlin3_pskey, 1),222CONF_ITEM_TABLE(g_nbv_nv_118, 0, marlin3_pskey, 1),223CONF_ITEM_TABLE(g_sys_sco_transmit_mode, 0, marlin3_pskey, 1),224CONF_ITEM_TABLE(audio_rfu_b1, 0, marlin3_pskey, 1),225CONF_ITEM_TABLE(audio_rfu_b2, 0, marlin3_pskey, 1),226CONF_ITEM_TABLE(audio_rfu_b3, 0, marlin3_pskey, 1),227CONF_ITEM_TABLE(audio_rfu_w, 0, marlin3_pskey, 2),228CONF_ITEM_TABLE(g_sys_sleep_in_standby_supported, 0, marlin3_pskey, 1),229CONF_ITEM_TABLE(g_sys_sleep_master_supported, 0, marlin3_pskey, 1),230CONF_ITEM_TABLE(g_sys_sleep_slave_supported, 0, marlin3_pskey, 1),231CONF_ITEM_TABLE(power_rfu_b1, 0, marlin3_pskey, 1),232CONF_ITEM_TABLE(power_rfu_w, 0, marlin3_pskey, 2),233CONF_ITEM_TABLE(win_ext, 0, marlin3_pskey, 1),234CONF_ITEM_TABLE(edr_tx_edr_delay, 0, marlin3_pskey, 1),235CONF_ITEM_TABLE(edr_rx_edr_delay, 0, marlin3_pskey, 1),236CONF_ITEM_TABLE(tx_delay, 0, marlin3_pskey, 1),237CONF_ITEM_TABLE(rx_delay, 0, marlin3_pskey, 1),238CONF_ITEM_TABLE(bb_rfu_w, 0, marlin3_pskey, 2),239CONF_ITEM_TABLE(agc_mode, 0, marlin3_pskey, 1),240CONF_ITEM_TABLE(diff_or_eq, 0, marlin3_pskey, 1),241CONF_ITEM_TABLE(ramp_mode, 0, marlin3_pskey, 1),242CONF_ITEM_TABLE(modem_rfu_b1, 0, marlin3_pskey, 1),243CONF_ITEM_TABLE(modem_rfu_w, 0, marlin3_pskey, 2),244CONF_ITEM_TABLE(BQB_BitMask_1, 0, marlin3_pskey, 1),245CONF_ITEM_TABLE(BQB_BitMask_2, 0, marlin3_pskey, 1),246CONF_ITEM_TABLE(bt_coex_threshold, 0, marlin3_pskey, 8),247CONF_ITEM_TABLE(other_rfu_w, 0, marlin3_pskey, 6),248{0, 0, 0, 0, 0}249};250251static const conf_entry_t marlin3_rf_table[] = {252CONF_ITEM_TABLE(g_GainValue_A, 0, marlin3_rf_config, 6),253CONF_ITEM_TABLE(g_ClassicPowerValue_A, 0, marlin3_rf_config, 10),254CONF_ITEM_TABLE(g_LEPowerValue_A, 0, marlin3_rf_config, 16),255CONF_ITEM_TABLE(g_BRChannelpwrvalue_A, 0, marlin3_rf_config, 8),256CONF_ITEM_TABLE(g_EDRChannelpwrvalue_A, 0, marlin3_rf_config, 8),257CONF_ITEM_TABLE(g_LEChannelpwrvalue_A, 0, marlin3_rf_config, 8),258CONF_ITEM_TABLE(g_GainValue_B, 0, marlin3_rf_config, 6),259CONF_ITEM_TABLE(g_ClassicPowerValue_B, 0, marlin3_rf_config, 10),260CONF_ITEM_TABLE(g_LEPowerValue_B, 0, marlin3_rf_config, 16),261CONF_ITEM_TABLE(g_BRChannelpwrvalue_B, 0, marlin3_rf_config, 8),262CONF_ITEM_TABLE(g_EDRChannelpwrvalue_B, 0, marlin3_rf_config, 8),263CONF_ITEM_TABLE(g_LEChannelpwrvalue_B, 0, marlin3_rf_config, 8),264CONF_ITEM_TABLE(LE_fix_powerword, 0, marlin3_rf_config, 1),265CONF_ITEM_TABLE(Classic_pc_by_channel, 0, marlin3_rf_config, 1),266CONF_ITEM_TABLE(LE_pc_by_channel, 0, marlin3_rf_config, 1),267CONF_ITEM_TABLE(RF_switch_mode, 0, marlin3_rf_config, 1),268CONF_ITEM_TABLE(Data_Capture_Mode, 0, marlin3_rf_config, 1),269CONF_ITEM_TABLE(Analog_IQ_Debug_Mode, 0, marlin3_rf_config, 1),270CONF_ITEM_TABLE(RF_common_rfu_b3, 0, marlin3_rf_config, 1),271CONF_ITEM_TABLE(RF_common_rfu_w, 0, marlin3_rf_config, 5),272{0, 0, 0, 0, 0}273};274275static void log_bin_to_hexstr(uint8_t *bin, uint8_t binsz, const char *log_tag)276{277SPRD_DBG("%s", log_tag);278SPRD_DUMP(bin, binsz);279}280281static void parse_number(char *p_conf_name, char *p_conf_value, void *buf, int len, int size)282{283uint8_t *dest = (uint8_t *)buf;284char *sub_value, *p;285uint32_t value;286(void)p_conf_name;287sub_value = strtok_r(p_conf_value, CONF_VALUES_PARTITION, &p);288do {289if (sub_value == NULL)290break;291292if (sub_value[0] == '0' && (sub_value[1] == 'x' || sub_value[1] == 'X'))293value = strtoul(sub_value, 0, 16) & 0xFFFFFFFF;294else295value = strtoul(sub_value, 0, 10) & 0xFFFFFFFF;296297switch (size) {298case sizeof(uint8_t):299*dest = value & 0xFF;300dest += size;301break;302303case sizeof(uint16_t):304*((uint16_t *)dest) = value & 0xFFFF;305dest += size;306break;307308case sizeof(uint32_t):309*((uint32_t *)dest) = value & 0xFFFFFFFF;310dest += size;311break;312313default:314break;315}316sub_value = strtok_r(NULL, CONF_VALUES_PARTITION, &p);317} while (--len);318}319320static unsigned char compare_char(unsigned char ch)321{322unsigned char data = 0x0;323324switch(ch)325{326case 0:327case '0':328data = 0x0;329break;330case 1:331case '1':332data = 0x1;333break;334case 2:335case '2':336data = 0x2;337break;338case 3:339case '3':340data = 0x3;341break;342case 4:343case '4':344data = 0x4;345break;346case 5:347case '5':348data = 0x5;349break;350case 6:351case '6':352data = 0x6;353break;354case 7:355case '7':356data = 0x7;357break;358case 8:359case '8':360data = 0x8;361break;362case 9:363case '9':364data = 0x9;365break;366case 10:367case 'a':368case 'A':369data = 0xA;370break;371case 11:372case 'b':373case 'B':374data = 0xB;375break;376case 12:377case 'c':378case 'C':379data = 0xC;380break;381case 13:382case 'd':383case 'D':384data = 0xD;385break;386case 14:387case 'e':388case 'E':389data = 0xE;390break;391case 15:392case 'f':393case 'F':394data = 0xF;395break;396}397return data;398}399400static void set_mac_address(uint8_t *addr)401{402int i = 0;403404FILE *fp = fopen("/sys/class/net/wlan0/address", "r");405unsigned char buff[255];406unsigned char tmp[5];407unsigned char str, str2;408409SPRD_DBG("%s", __func__);410411fscanf(fp, "%s", buff);412fclose(fp);413414for (i=0; i<6; i++)415{416sprintf(tmp, "%c%c", buff[3*i], buff[3*i+1]);417str = compare_char(tmp[0]);418str2 = compare_char(tmp[1]);419local_bdaddr[i] = (str << 4) | str2;420}421422for (i = 0; i < 6; i++)423addr[5-i] = (unsigned char)local_bdaddr[i];424425addr[0] += 1;426addr[1] += 1;427}428429static void vnd_load_configure(const char *p_path, const conf_entry_t *entry)430{431FILE *p_file;432char *p_name, *p_value, *p;433conf_entry_t *p_entry;434char line[CONF_MAX_LINE_LEN + 1]; /* add 1 for \0 char */435436SPRD_DBG("Attempt to load conf from %s", p_path);437438if ((p_file = fopen(p_path, "r")) != NULL) {439/* read line by line */440while (fgets(line, CONF_MAX_LINE_LEN + 1, p_file) != NULL) {441if (line[0] == CONF_COMMENT) continue;442443p_name = strtok_r(line, CONF_DELIMITERS, &p);444445if (NULL == p_name) {446continue;447}448449p_value = strtok_r(NULL, CONF_VALUES_DELIMITERS, &p);450451if (NULL == p_value) {452SPRD_DBG("vnd_load_conf: missing value for name: %s", p_name);453continue;454}455456p_entry = (conf_entry_t*)entry;457458while (p_entry->conf_entry != NULL) {459if (strcmp(p_entry->conf_entry, (const char *)p_name) == 0) {460if (p_entry->p_action) {461p_entry->p_action(p_name, p_value, p_entry->buf, p_entry->len,462p_entry->size);463} else {464SPRD_DBG("%s -> %s", p_name, p_value);465parse_number(p_name, p_value, p_entry->buf, p_entry->len,466p_entry->size);467}468break;469}470471p_entry++;472}473}474475fclose(p_file);476} else {477SPRD_DBG("vnd_load_conf file >%s< not found", p_path);478}479}480481static size_t H4Protocol_Send(uint8_t type, const uint8_t* data, size_t length)482{483struct iovec iov[] = {484{&type, sizeof(type)},485{(uint8_t *)data, length}};486487ssize_t ret = 0;488do {489ret = writev(s_bt_fd, iov, sizeof(iov) / sizeof(iov[0]));490} while (-1 == ret && EAGAIN == errno);491492if (ret == -1) {493SPRD_ERR("%s error writing to UART (%s)", __func__, strerror(errno));494} else if (ret < length + 1) {495SPRD_ERR("%s: %d / %d bytes written - something went wrong...", __func__, ret, length + 1);496}497498return ret;499}500501static void *bt_vendor_alloc(int size)502{503void *p = (uint8_t *)malloc(size);504return p;505}506507static void bt_vendor_free(void *buffer)508{509free(buffer);510}511512static uint8_t bt_vendor_xmit(uint16_t opcode, void* buffer, hci_cback callback)513{514uint8_t type = HCI_PACKET_TYPE_COMMAND;515(void)opcode;516HC_BT_HDR* bt_hdr = (HC_BT_HDR *)buffer;517H4Protocol_Send(type, bt_hdr->data, bt_hdr->len);518return BT_VND_OP_RESULT_SUCCESS;519}520521static uint8_t sprd_vnd_send_hci_vsc(uint16_t cmd, uint8_t *payload, uint8_t len, hci_cback cback)522{523HC_BT_HDR *p_buf;524uint8_t *p, ret;525526p_buf = (HC_BT_HDR *)bt_vendor_alloc(527BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + len);528if (p_buf) {529p_buf->event = MSG_STACK_TO_HC_HCI_CMD;530p_buf->offset = 0;531p_buf->layer_specific = 0;532p_buf->len = HCI_CMD_PREAMBLE_SIZE + len;533p = (uint8_t *)(p_buf + 1);534535UINT16_TO_STREAM(p, cmd);536*p++ = len;537memcpy(p, payload, len);538log_bin_to_hexstr((uint8_t *)(p_buf + 1), HCI_CMD_PREAMBLE_SIZE + len, __FUNCTION__);539ret = bt_vendor_xmit(cmd, p_buf, cback);540bt_vendor_free(p_buf);541return ret;542}543return BT_VND_OP_RESULT_FAIL;544}545546static void hw_core_cback(void *p_mem)547{548uint8_t *p_evt_buf = (uint8_t *)p_mem;549uint8_t *p, status;550uint16_t opcode, mode;551552p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;553STREAM_TO_UINT16(opcode,p);554STREAM_TO_UINT16(mode,p);555STREAM_TO_UINT8(status,p);556SPRD_DBG("%s hw_core_cback response: [0x%04X, 0x%04X, 0x%02X]", __func__, opcode, mode, status);557bt_vendor_free(p_evt_buf);558}559560static void hw_core_enable(unsigned char enable)561{562uint8_t *p, msg_req[HCI_CMD_MAX_LEN];563p = msg_req;564UINT16_TO_STREAM(p, DUAL_MODE);565UINT8_TO_STREAM(p, enable ? ENABLE_BT : DISABLE_BT);566sprd_vnd_send_hci_vsc(HCI_VSC_ENABLE_COMMMAND, msg_req, (uint8_t)(p - msg_req), NULL);567}568569static void hw_rf_cback(void *p_mem)570{571uint8_t *p_evt_buf = (uint8_t *)p_mem, len;572uint8_t *p, status;573uint16_t opcode, mode = 0;574575p = (uint8_t *)(p_evt_buf + 1) + 1;576STREAM_TO_UINT8(len, p);577578p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;579STREAM_TO_UINT16(opcode, p);580if (len == 6)581STREAM_TO_UINT16(mode, p);582583STREAM_TO_UINT8(status, p);584585SPRD_DBG("%s hw_rf_cback response: [0x%04X, 0x%04X, 0x%02X]", __func__, opcode, mode, status);586/* Must free the RX event buffer */587bt_vendor_free(p_evt_buf);588}589590static int marlin3_rf_preload()591{592uint8_t *p, msg_req[HCI_CMD_MAX_LEN];593int i;594595SPRD_DBG("yujian.qin %s", __FUNCTION__);596p = msg_req;597598for (i = 0; i < 6; i++)599UINT16_TO_STREAM(p, marlin3_rf_config.g_GainValue_A[i]);600601for (i = 0; i < 10; i++)602UINT16_TO_STREAM(p, marlin3_rf_config.g_ClassicPowerValue_A[i]);603604for (i = 0; i < 16; i++)605UINT16_TO_STREAM(p, marlin3_rf_config.g_LEPowerValue_A[i]);606607for (i = 0; i < 8; i++)608UINT16_TO_STREAM(p, marlin3_rf_config.g_BRChannelpwrvalue_A[i]);609610for (i = 0; i < 8; i++)611UINT16_TO_STREAM(p, marlin3_rf_config.g_EDRChannelpwrvalue_A[i]);612613for (i = 0; i < 8; i++)614UINT16_TO_STREAM(p, marlin3_rf_config.g_LEChannelpwrvalue_A[i]);615616for (i = 0; i < 6; i++)617UINT16_TO_STREAM(p, marlin3_rf_config.g_GainValue_B[i]);618619for (i = 0; i < 10; i++)620UINT16_TO_STREAM(p, marlin3_rf_config.g_ClassicPowerValue_B[i]);621622for (i = 0; i < 16; i++)623UINT16_TO_STREAM(p, marlin3_rf_config.g_LEPowerValue_B[i]);624625for (i = 0; i < 8; i++)626UINT16_TO_STREAM(p, marlin3_rf_config.g_BRChannelpwrvalue_B[i]);627628for (i = 0; i < 8; i++)629UINT16_TO_STREAM(p, marlin3_rf_config.g_EDRChannelpwrvalue_B[i]);630631for (i = 0; i < 8; i++)632UINT16_TO_STREAM(p, marlin3_rf_config.g_LEChannelpwrvalue_B[i]);633634UINT16_TO_STREAM(p, marlin3_rf_config.LE_fix_powerword);635636UINT8_TO_STREAM(p, marlin3_rf_config.Classic_pc_by_channel);637UINT8_TO_STREAM(p, marlin3_rf_config.LE_pc_by_channel);638UINT8_TO_STREAM(p, marlin3_rf_config.RF_switch_mode);639UINT8_TO_STREAM(p, marlin3_rf_config.Data_Capture_Mode);640UINT8_TO_STREAM(p, marlin3_rf_config.Analog_IQ_Debug_Mode);641UINT8_TO_STREAM(p, marlin3_rf_config.RF_common_rfu_b3);642643for (i = 0; i < 5; i++)644UINT32_TO_STREAM(p, marlin3_rf_config.RF_common_rfu_w[i]);645646sprd_vnd_send_hci_vsc(HCI_RF_PARA, msg_req, (uint8_t)(p - msg_req), NULL);647return 0;648}649650static void marlin3_pskey_cback(void *p_mem)651{652uint8_t *p_evt_buf = (uint8_t *)p_mem;653654uint16_t opcode, node, year;655uint8_t *p, month, day;656(void)opcode;657658p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;659STREAM_TO_UINT16(opcode, p);660661p = (uint8_t *)(p_evt_buf + 1) + FW_NODE_BYTE;662STREAM_TO_UINT16(node, p);663p = (uint8_t *)(p_evt_buf + 1) + FW_DATE_Y_BYTE;664STREAM_TO_UINT16(year, p);665p = (uint8_t *)(p_evt_buf + 1) + FW_DATE_M_BYTE;666STREAM_TO_UINT8(month, p);667p = (uint8_t *)(p_evt_buf + 1) + FW_DATE_D_BYTE;668STREAM_TO_UINT8(day, p);669670SPRD_DBG("Bluetooth Firmware Node: %04X Date: %04x-%02x-%02x", node, year, month, day);671672/* Must free the RX event buffer */673bt_vendor_free(p_evt_buf);674}675676static int marlin3_pskey_preload(void *arg)677{678uint8_t *p, msg_req[HCI_CMD_MAX_LEN];679int i;680(void)arg;681682SPRD_DBG("%s", __FUNCTION__);683p = msg_req;684UINT32_TO_STREAM(p, marlin3_pskey.device_class);685686for (i = 0; i < 16; i++)687UINT8_TO_STREAM(p, marlin3_pskey.feature_set[i]);688689for (i = 0; i < 6; i++)690UINT8_TO_STREAM(p, marlin3_pskey.device_addr[i]);691692UINT16_TO_STREAM(p, marlin3_pskey.comp_id);693UINT8_TO_STREAM(p, marlin3_pskey.g_sys_uart0_communication_supported);694UINT8_TO_STREAM(p, marlin3_pskey.cp2_log_mode);695UINT8_TO_STREAM(p, marlin3_pskey.LogLevel);696UINT8_TO_STREAM(p, marlin3_pskey.g_central_or_perpheral);697698UINT16_TO_STREAM(p, marlin3_pskey.Log_BitMask);699UINT8_TO_STREAM(p, marlin3_pskey.super_ssp_enable);700UINT8_TO_STREAM(p, marlin3_pskey.common_rfu_b3);701702for (i = 0; i < 2; i++)703UINT32_TO_STREAM(p, marlin3_pskey.common_rfu_w[i]);704705for (i = 0; i < 2; i++)706UINT32_TO_STREAM(p, marlin3_pskey.le_rfu_w[i]);707708for (i = 0; i < 2; i++)709UINT32_TO_STREAM(p, marlin3_pskey.lmp_rfu_w[i]);710711for (i = 0; i < 2; i++)712UINT32_TO_STREAM(p, marlin3_pskey.lc_rfu_w[i]);713714UINT16_TO_STREAM(p, marlin3_pskey.g_wbs_nv_117);715UINT16_TO_STREAM(p, marlin3_pskey.g_wbs_nv_118);716UINT16_TO_STREAM(p, marlin3_pskey.g_nbv_nv_117);717UINT16_TO_STREAM(p, marlin3_pskey.g_nbv_nv_118);718719UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sco_transmit_mode);720UINT8_TO_STREAM(p, marlin3_pskey.audio_rfu_b1);721UINT8_TO_STREAM(p, marlin3_pskey.audio_rfu_b2);722UINT8_TO_STREAM(p, marlin3_pskey.audio_rfu_b3);723724for (i = 0; i < 2; i++)725UINT32_TO_STREAM(p, marlin3_pskey.audio_rfu_w[i]);726727UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sleep_in_standby_supported);728UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sleep_master_supported);729UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sleep_slave_supported);730UINT8_TO_STREAM(p, marlin3_pskey.power_rfu_b1);731732for (i = 0; i < 2; i++)733UINT32_TO_STREAM(p, marlin3_pskey.power_rfu_w[i]);734735UINT32_TO_STREAM(p, marlin3_pskey.win_ext);736737UINT8_TO_STREAM(p, marlin3_pskey.edr_tx_edr_delay);738UINT8_TO_STREAM(p, marlin3_pskey.edr_rx_edr_delay);739UINT8_TO_STREAM(p, marlin3_pskey.tx_delay);740UINT8_TO_STREAM(p, marlin3_pskey.rx_delay);741742for (i = 0; i < 2; i++)743UINT32_TO_STREAM(p, marlin3_pskey.bb_rfu_w[i]);744745UINT8_TO_STREAM(p, marlin3_pskey.agc_mode);746UINT8_TO_STREAM(p, marlin3_pskey.diff_or_eq);747UINT8_TO_STREAM(p, marlin3_pskey.ramp_mode);748UINT8_TO_STREAM(p, marlin3_pskey.modem_rfu_b1);749750for (i = 0; i < 2; i++)751UINT32_TO_STREAM(p, marlin3_pskey.modem_rfu_w[i]);752753UINT32_TO_STREAM(p, marlin3_pskey.BQB_BitMask_1);754UINT32_TO_STREAM(p, marlin3_pskey.BQB_BitMask_2);755for (i = 0; i < 8; i++)756UINT16_TO_STREAM(p, marlin3_pskey.bt_coex_threshold[i]);757758for (i = 0; i < 6; i++)759UINT32_TO_STREAM(p, marlin3_pskey.other_rfu_w[i]);760761sprd_vnd_send_hci_vsc(HCI_PSKEY, msg_req, (uint8_t)(p - msg_req), NULL);762return 0;763}764765766int sprd_config_init(int fd, struct uart_t *u, struct termios *ti)767{768uint8_t *recv = NULL;769int len = 0;770771s_bt_fd = fd;772773memset(&marlin3_pskey, 0, sizeof(marlin3_pskey));774memset(&marlin3_rf_config, 0, sizeof(marlin3_rf_config));775vnd_load_configure(BT_CONFIG_PATH "/bt_configure_pskey.ini", &marlin3_pksey_table[0]);776vnd_load_configure(BT_CONFIG_PATH "/bt_configure_rf.ini", &marlin3_rf_table[0]);777set_mac_address(marlin3_pskey.device_addr);778779marlin3_pskey_preload(NULL);780recv = bt_vendor_alloc(RESPONSE_LENGTH);781len = read_hci_event(s_bt_fd, recv, RESPONSE_LENGTH);782SPRD_DBG("Received event, len: %d", len);783SPRD_DUMP(recv, len);784marlin3_pskey_cback(recv);785786marlin3_rf_preload();787recv = bt_vendor_alloc(RESPONSE_LENGTH);788len = read_hci_event(s_bt_fd, recv, RESPONSE_LENGTH);789SPRD_DBG("Received event, len: %d", len);790SPRD_DUMP(recv, len);791hw_rf_cback(recv);792793hw_core_enable(1);794recv = bt_vendor_alloc(RESPONSE_LENGTH);795len = read_hci_event(s_bt_fd, recv, RESPONSE_LENGTH);796SPRD_DBG("Received event, len: %d", len);797SPRD_DUMP(recv, len);798hw_core_cback(recv);799800return 0;801}802803int sprd_config_post(int fd, struct uart_t *u, struct termios *ti)804{805SPRD_DBG("Done setting line discpline");806return 0;807}808809810811